home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 June: Reference Library / Dev.CD Jun 94.toast / Technical Documentation / Inside Macintosh / IM—QuickDraw GX ß3 / Graphics / Graphics
Encoding:
Text File  |  1994-04-27  |  19.4 MB  |  102,316 lines  |  [ONLN/HLX2]

Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
  1. INSIDE MACINTOSH
  2.  
  3. QuickDraw GX Graphics
  4.     Apple Computer, Inc.
  5. © 1994 Apple Computer, Inc.
  6. All rights reserved. 
  7. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, mechanical, electronic, photocopying, recording, or otherwise, without prior written permission of Apple Computer, Inc. Printed in the United States of America.
  8. No licenses, express or implied, are granted with respect to any of the technology described in this book. Apple retains all intellectual property rights associated with the technology described in this book. This book is intended to assist application developers to develop applications only for Apple Macintosh computers.
  9. Every effort has been made to ensure that the information in this manual is accurate. Apple is not responsible for printing or clerical errors.
  10. Apple Computer, Inc.
  11. 20525 Mariani Avenue
  12. Cupertino, CA 95014
  13. 408-996-1010
  14. Apple, the Apple logo, LaserWriter, and Macintosh are trademarks of Apple Computer, Inc., registered in the United States and other countries.
  15. Adobe Illustrator, Adobe Photoshop, and PostScript are trademarks of Adobe Systems Incorporated, which may be registered in certain jurisdictions.
  16. FrameMaker is a registered trademark of Frame Technology Corporation.
  17. Helvetica and Palatino are registered trademarks of Linotype Company.
  18. ITC Zapf Dingbats is a registered trademark of International Typeface Corporation.
  19. Optrotech is a trademark of Orbotech Corporation.
  20. Simultaneously published in the United States and Canada.
  21. LIMITED WARRANTY ON MEDIA AND REPLACEMENT
  22. ALL IMPLIED WARRANTIES ON THIS MANUAL, INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE LIMITED IN DURATION TO NINETY (90) DAYS FROM THE DATE OF THE ORIGINAL RETAIL PURCHASE OF THIS PRODUCT.
  23. Even though Apple has reviewed this manual, APPLE MAKES NO WARRANTY OR REPRESENTATION, EITHER EXPRESS OR IMPLIED, WITH RESPECT TO THIS MANUAL, ITS QUALITY, ACCURACY, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. AS A RESULT, THIS MANUAL IS SOLD “AS IS,” AND YOU, THE PURCHASER, ARE ASSUMING THE ENTIRE RISK AS TO ITS QUALITY AND ACCURACY.
  24. IN NO EVENT WILL APPLE BE LIABLE FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES RESULTING FROM ANY DEFECT OR INACCURACY IN THIS MANUAL, even if advised of the possibility of such damages.
  25. THE WARRANTY AND REMEDIES SET FORTH ABOVE ARE EXCLUSIVE AND IN LIEU OF ALL OTHERS, ORAL OR WRITTEN, EXPRESS OR IMPLIED. No Apple dealer, agent, or employee is authorized to make any modification, extension, or addition to this warranty.
  26. Some states do not allow the exclusion or limitation of implied warranties or liability for incidental or consequential damages, so the above limitation or exclusion may not apply to you. This warranty gives you specific legal rights, and you may also have other rights which vary from state to state.
  27. ISBN 0-201-nnnnn-n
  28. 1 2 3 4 5 6 7 8 9-CRW-9897969594
  29. First Printing, Month 1994
  30. Contents
  31. Figures, Tables, and Listingsxi
  32. Preface    About This Bookxxi
  33.  
  34. What to Readxxi
  35. Chapter Organizationxxii
  36. Conventions Used in This Bookxxii
  37. Special Fontsxxiii
  38. Types of Notesxxiii
  39. Numerical Formatsxxiii
  40. Illustrationsxxiii
  41. Development Environmentxxiv
  42. Developer Products and Supportxxiv
  43. Chapter 1    Introduction to QuickDraw GX Graphics1-1
  44.  
  45. About QuickDraw GX Graphics1-3
  46. Geometric Shapes1-6
  47. Geometric Shape Types1-6
  48. Geometric Shape Geometries1-7
  49. Geometric Shape Fills1-8
  50. Geometric Styles, Inks, and Transforms1-9
  51. Geometric Operations1-11
  52. Bitmap Shapes1-15
  53. Picture Shapes1-17
  54. Chapter 2    Geometric Shapes2-1
  55.  
  56. About Geometric Shapes2-5
  57. The Geometric Properties of Shape Objects2-7
  58. Shape Type2-7
  59. Shape Geometry2-8
  60. Shape Fill2-10
  61. The Geometric Shape Types2-14
  62. Empty Shapes and Full Shapes2-15
  63. Point Shapes2-15
  64. Line Shapes2-16
  65. Curve Shapes2-17
  66. Rectangle Shapes2-19
  67. Polygon Shapes2-20
  68. Path Shapes2-23
  69. Using Geometric Shapes2-25
  70. Creating and Drawing Empty Shapes and Full Shapes2-26
  71. Creating and Drawing Points2-27
  72. Creating and Drawing Lines2-32
  73. Creating and Drawing Rectangles2-36
  74. Creating and Drawing Curves2-39
  75. Creating and Drawing Polygons2-40
  76. Creating Polygons With a Single Contour2-41
  77. Creating Polygons With Mulitple Contours2-44
  78. Creating Polygons With Crossed Contours2-45
  79. Creating and Drawing Paths2-49
  80. Creating Paths With a Single Contour2-50
  81. Creating Paths Using Only Off-Curve Points2-52
  82. Creating Paths With Multiple Contours2-53
  83. Converting Shapes to Points, Lines, and Rectangles2-57
  84. Converting Shapes to Curve Shapes2-61
  85. Converting Shapes to Polygons and Paths2-65
  86. Replacing Geometric Points2-68
  87. Editing Polygon Parts2-71
  88. Editing Paths Parts2-79
  89. Editing Shape Parts2-81
  90. Applying Functions Described Elsewhere to Geometric Shapes2-86
  91. Shape-Related Functions Applicable to Geometric Shapes2-86
  92. Geometric Operations Applicable to Geometric Shapes2-88
  93. Style-Related Functions Applicable to Geometric Shapes2-89
  94. Ink-Related Functions Applicable to Geometric Shapes2-89
  95. Transform-Related Functions Applicable to Geometric Shapes2-89
  96. Geometric Shapes Reference2-89
  97. Data Types2-90
  98. Point Structure2-90
  99. Line Structure2-91
  100. Curves2-91
  101. Rectangle Structure2-91
  102. Polygon Structures2-92
  103. Path Structures2-93
  104. Functions2-94
  105. Creating Geometric Shapes2-94
  106. Getting and Setting Shape Geometries2-102
  107. Editing Shape Geometries2-115
  108. Drawing Geometric Shapes2-134
  109. Summary of Geometric Shapes2-139
  110. Constants and Data Types2-139
  111. Functions2-140
  112. Chapter 3    Geometric Styles3-1
  113.  
  114. About Geometric Styles3-5
  115. Shapes and Styles3-5
  116. Incorporating Stylistic Variations Into Shape Geometries3-9
  117. Style Properties3-12
  118. Default Style Objects3-13
  119. Curve Error3-14
  120. The Geometric Pen3-15
  121. Style Attributes3-17
  122. Pen Placement3-18
  123. Grids3-21
  124. Caps, Joins, Dashes and Patterns3-22
  125. Caps3-23
  126. Joins3-25
  127. Dashes3-27
  128. Patterns3-31
  129. Interactions Between Caps, Joins, Dashes, and Patterns3-33
  130. Using Geometric Styles3-35
  131. Associating Styles With Shapes3-36
  132. Constraining Shape Geometries to Grids3-39
  133. Constraining Shapes to Device Grids3-41
  134. Converting Paths to Polygons3-43
  135. Using Curve Error When Reducing Shapes3-46
  136. Manipulating Pen Width and Placement3-48
  137. Adding Caps to a Shape3-53
  138. Adding Standard Caps to a Shape3-56
  139. Adding Joins to a Shape3-58
  140. Adding Standard Joins to a Shape3-61
  141. Dashing a Shape3-63
  142. Adjusting Dashes to Fit Contours3-67
  143. Insetting Dashes3-69
  144. Breaking and Bending Dashes3-71
  145. Wrapping Text3-75
  146. Determining Dash Positions3-77
  147. Adding a Pattern to a Shape3-81
  148. Determining Pattern Positions3-83
  149. Combining Caps, Joins, Dashes, and Patterns3-86
  150. Geometric Styles Reference3-90
  151. Constants and Data Types3-91
  152. Style Objects3-91
  153. Style Attributes3-92
  154. Cap Record Structure3-94
  155. Cap Attributes3-95
  156. Join Record Structure3-95
  157. Join Attributes3-96
  158. Dash Record Structure3-97
  159. Dash Attributes3-98
  160. Pattern Record Structure3-99
  161. Pattern Attributes3-100
  162. Functions3-101
  163. Getting and Setting Style Attributes3-102
  164. Getting and Setting Curve Error3-107
  165. Getting and Setting the Pen Width3-112
  166. Getting and Setting Start Caps and End Caps3-116
  167. Getting and Setting Joins3-121
  168. Getting and Setting Dashes3-126
  169. Getting and Setting Patterns3-132
  170. Summary of Geometric Styles3-140
  171. Constants and Data Types3-140
  172. Functions for Manipulating Geometric Style Properties3-142
  173. Chapter 4    Geometric Operations4-1
  174.  
  175. About Geometric Operations4-3
  176. Contours and Contour Direction4-4
  177. Reducing and Simplifying Shape Geometries4-8
  178. The Primitive Form of Shape Geometries4-10
  179. Geometric Information4-14
  180. Intersection and Inclusion4-16
  181. Geometric Arithmetic4-19
  182. Using Geometric Operations4-21
  183. Determining and Reversing Contour Direction4-21
  184. Breaking Shape Contours4-25
  185. Eliminating Unnecessary Geometric Points4-27
  186. Simplifying Shapes4-29
  187. Converting a Shape to Primitive Form4-34
  188. Finding Geometric Information About a Shape4-36
  189. Setting a Shape’s Bounding Rectangle4-42
  190. Insetting Shapes4-45
  191. Determining Whether Two Shapes Touch4-47
  192. Determining Whether One Shape Contains Another4-51
  193. Performing Geometric Arithmetic With Shapes4-53
  194. Geometric Operations Reference4-60
  195. Constants and Data Types4-60
  196. Contour Directions4-60
  197. Functions4-60
  198. Determining and Reversing Contour Direction4-61
  199. Breaking Shape Contours4-64
  200. Reducing and Simplifying Shapes4-65
  201. Incorporating Style Information Into Shape Geometries4-69
  202. Finding Geometric Information About Shapes4-71
  203. Getting and Setting Shape Bounds4-76
  204. Insetting Shapes4-79
  205. Determining Whether Two Areas Intersect4-80
  206. Determining Whether One Shape Contains Another4-83
  207. Performing Geometric Arithmetic with Shapes4-87
  208. Summary of Geometric Operations4-98
  209. Constants and Data Types4-98
  210. Functions4-98
  211. Chapter 5    Bitmap Shapes5-1
  212.  
  213. About Bitmap Shapes5-3
  214. Bitmap Geometries5-4
  215. Bitmap Styles and Inks5-7
  216. Bitmap Transforms5-8
  217. Bitmaps and View Devices5-10
  218. Using Bitmap Shapes5-13
  219. Creating and Drawing Bitmaps5-13
  220. Creating Black-and-White Bitmaps5-14
  221. Creating Color Bitmaps5-19
  222. Dithering and Halftoning Bitmaps5-28
  223. Applying Transfer Modes to Bitmaps5-30
  224. Converting Other Types of Shapes to Bitmaps5-32
  225. Applying Transformations to Bitmaps5-35
  226. Creating Bitmaps With Disk-Based Pixel Images5-40
  227. Creating Bitmaps Offscreen5-42
  228. Editing Parts of a Bitmap5-49
  229. Applying Functions Described Elsewhere to Bitmap Shapes5-51
  230. Functions That Post Errors or Warnings When Applied to Bitmap Shapes5-51
  231. Shape-Related Functions Applicable to Bitmap Shapes5-53
  232. Geometric Operations Applicable to Bitmap Shapes5-54
  233. Style-Related Functions Applicable to Bitmap Shapes5-55
  234. Ink-Related and Color-Related Functions Applicable to Bitmap Shapes5-55
  235. Transform-Related Functions Applicable to Bitmap Shapes5-55
  236. View-Related Functions That Can Be Applied to Bitmap Shapes5-57
  237. Bitmap Shapes Reference5-58
  238. Data Types5-58
  239. The Bitmap Geometry Structure5-58
  240. The Long Rectangle Structure5-60
  241. Constants For Bitmaps With Disk-Based Pixel Images5-60
  242. Bitmap Data Source Alias Structure5-61
  243. Functions5-61
  244. Creating Bitmaps5-62
  245. Getting and Setting Bitmap Geometries5-64
  246. Editing Bitmaps5-67
  247. Drawing Bitmaps5-72
  248. Checking Bitmap Colors5-74
  249. Summary of Bitmap Shapes5-76
  250. Data Types5-76
  251. Functions5-77
  252. Chapter 6    Picture Shapes6-1
  253.  
  254. About Picture Shapes6-3
  255. Overriding Styles, Inks, and Transforms6-7
  256. Multiple References6-9
  257. Unique Items Attribute6-13
  258. Picture Hierarchies6-14
  259. Transform Concatenation6-15
  260. Hit-Testing Picture Shapes6-20
  261. Using Picture Shapes6-22
  262. Creating and Drawing Picture Shapes6-22
  263. Getting and Setting Picture Geometries6-26
  264. Adding Items to a Picture6-28
  265. Removing and Replacing Items in a Picture6-31
  266. Overriding Styles, Inks, and Transforms6-33
  267. Adding Multiple References6-35
  268. Adding Unique Items6-37
  269. Creating Picture Hierarchies6-39
  270. Hit-Testing Pictures6-40
  271. Applying Functions Described Elsewhere to Picture Shapes6-46
  272. Functions That Post Errors or Warnings6-46
  273. Shape-Related Functions6-47
  274. Geometric Operations6-48
  275. Style-Related Functions6-49
  276. Ink- and Color-Related Functions6-49
  277. Transform- and View-Related Functions6-49
  278. Picture Shapes Reference6-50
  279. Functions6-50
  280. Creating Picture Shapes6-50
  281. Getting and Setting Picture Geometries6-52
  282. Editing Picture Parts6-55
  283. Drawing Pictures6-59
  284. Hit-Testing Pictures6-61
  285. Summary of Picture Shapes6-64
  286. Data Types6-64
  287. Functions6-64
  288. GlossaryGL-1
  289.  
  290. IndexIN-1
  291. Figures, Tables, and Listings
  292. Chapter 1    Introduction to QuickDraw GX Graphics1-1
  293.  
  294. Figure 1-1    Shape object structure1-4
  295. Table 1-1    Where to find information on shape-type conversion1-5
  296. Figure 1-2    The geometric shape types and examples of geometric shape geometries1-7
  297. Figure 1-3    A polygon shape with a single polygon contour containing three geometric points1-8
  298. Figure 1-4    Framing shapes versus filling shapes1-9
  299. Figure 1-5    Two condensed views of a polygon shape1-10
  300. Figure 1-6    The geometric style properties and some examples of their effects1-11
  301. Figure 1-7    An example of eliminating unnecessary geometric points from a shape1-12
  302. Figure 1-8    An example of simplifying a shape1-12
  303. Figure 1-9    Some examples of the geometric information available about a shape1-13
  304. Figure 1-10    Some examples of the geometric arithmetic you can perform with shapes1-14
  305. Figure 1-11    Sample bitmap shapes1-15
  306. Figure 1-12    A bitmap shape 1-16
  307. Figure 1-13    Elements of a bitmap geometry1-17
  308. Figure 1-14    Sample picture shapes1-18
  309. Figure 1-15    A picture shape1-18
  310. Figure 1-16    A picture hierarchy1-19
  311. Chapter 2    Geometric Shapes2-1
  312.  
  313. Figure 2-1    A shape object2-6
  314. Figure 2-2    The geometric shape types and examples of geometric shape geometries2-8
  315. Figure 2-3    A polygon shape with a single contour containing three geometric points2-9
  316. Figure 2-4    Framing shapes versus filling shapes2-11
  317. Figure 2-5    The various shape fills and some examples of their effects2-12
  318. Figure 2-6    The even-odd rule and winding-number rule algorithms2-13
  319. Figure 2-7    Two lines2-16
  320. Figure 2-8    A quadratic Bézier curve2-17
  321. Figure 2-9    Finding the midpoint of a curve2-18
  322. Figure 2-10    Dividing a curve into two smaller curves2-18
  323. Figure 2-11    A rectangle geometry shown framed and filled2-19
  324. Figure 2-12    A polygon shape with two polygon contours2-21
  325. Figure 2-13    A polygon drawn with the even-odd and winding shape fills2-22
  326. Figure 2-14    A polygon filled with the inverseFill shape fill2-22
  327. Figure 2-15    A path with two consecutive off-curve points2-24
  328. Figure 2-16    A path shape filled with the evenOddFill and windingFill shape fills2-24
  329. Listing 2-1    Drawing a point without creating a point shape2-27
  330. Figure 2-17    A point2-28
  331. Listing 2-2    Creating a point shape with the GXNewPoint function2-29
  332. Listing 2-3    Creating a point shape with the GXNewShapeVector function2-29
  333. Listing 2-4    Creating a point shape with the GXNewShape and GXSetPoint functions2-30
  334. Listing 2-5    Using the GXSetPoint function to replace a point shape’s geometry2-30
  335. Figure 2-18    Two different point geometries2-31
  336. Listing 2-6    Drawing a line without creating a line shape2-32
  337. Figure 2-19    A line2-33
  338. Listing 2-7    Creating a line shape with the GXNewLine function2-33
  339. Listing 2-8    Drawing two parallel lines2-34
  340. Figure 2-20    Parallel lines2-35
  341. Figure 2-21    Nearly parallel lines2-36
  342. Listing 2-9    Creating a rectangle shape2-37
  343. Figure 2-22    A rectangle2-37
  344. Listing 2-10    Creating a framed rectangle2-38
  345. Figure 2-23    A framed rectangle2-38
  346. Listing 2-11    Creating a curve shape2-39
  347. Figure 2-24    A curve shape2-40
  348. Listing 2-12    Drawing a triangular polygon2-42
  349. Figure 2-25    A triangular polygon2-42
  350. Figure 2-26    A triangular polygon with an inverse shape fill2-43
  351. Listing 2-13    Creating a polygon with two contours2-44
  352. Figure 2-27    A filled polygon with two separate contours2-44
  353. Listing 2-14    Creating a polygon with a crossed contour2-45
  354. Figure 2-28    A framed polygon with a crossed contour2-45
  355. Figure 2-29    A filled polygon with crossed contour2-46
  356. Listing 2-15    Creating a polygon with an overlapping contour2-46
  357. Figure 2-30    A framed polygon with an overlapping contour and closed-frame shape fill2-47
  358. Figure 2-31    A even-odd filled polygon with an overlapping contour and even-odd shape fill2-48
  359. Figure 2-32    A contour with an overlapping contour and winding shape fill2-48
  360. Listing 2-16    Drawing a path shape2-50
  361. Figure 2-33    A path2-51
  362. Listing 2-17    Creating a path using only off-curve control points2-52
  363. Figure 2-34    A round path shape2-53
  364. Listing 2-18    Creating a path with concentric contours2-53
  365. Figure 2-35    A framed path shape with two concentric clockwise contours2-54
  366. Figure 2-36    An even-odd filled path shape with two concentric clockwise contours2-55
  367. Figure 2-37    A winding-filled path shape with two concentric clockwise contours2-55
  368. Figure 2-38    A framed paths shape with an internal counterclockwise contour2-56
  369. Figure 2-39    A filled path shape with an internal counterclockwise contour2-57
  370. Listing 2-19    Creating a figure-eight path shape2-59
  371. Figure 2-40    A figure-eight path shape2-59
  372. Figure 2-41    The result of converting a path shape to a rectangle shape2-60
  373. Figure 2-42    The result of converting a path shape to a line shape2-60
  374. Figure 2-43    A path shape converted to a point shape2-61
  375. Listing 2-20    Converting a line to a curve2-62
  376. Figure 2-44    A line shape before and after conversion to a curve shape2-62
  377. Listing 2-21    Converting a rectangle to a curve2-63
  378. Figure 2-45    A rectangle shape before and after conversion to a curve shape2-63
  379. Listing 2-22    Converting a polygon shape to a curve shape2-64
  380. Figure 2-46    A polygon shape before and after conversion to a curve shape2-64
  381. Listing 2-23    Converting a rectangle shape to a polygon shape2-65
  382. Figure 2-47    A rectangle shape before and after conversion to a polygon shape2-66
  383. Listing 2-24    Converting a path shape to a polygon shape2-66
  384. Figure 2-48    A path shape before and after conversion to a polygon shape2-67
  385. Listing 2-25    Converting a polygon shape to a path shape2-67
  386. Figure 2-49    Polygon shape with two contours before and after conversion to a path shape2-68
  387. Listing 2-26    Replacing geometric points2-69
  388. Figure 2-50    A paths shape with a flat top2-70
  389. Figure 2-51    A paths shape with geometric points replaced2-70
  390. Listing 2-27    Creating a polygon shape with two contours2-71
  391. Figure 2-52    A polygon shape with two contours2-72
  392. Listing 2-28    Extracting part of a polygons shape2-73
  393. Figure 2-53    A polygon shape extracted from a larger polygon shape2-74
  394. Listing 2-29    Replacing geometric points of a polygons shape2-74
  395. Figure 2-54    A polygon with two geometric points replaced by a single geometric point2-75
  396. Figure 2-55    A closed-frame filled polygon2-76
  397. Listing 2-30    Creating a hollow polygon2-76
  398. Figure 2-56    A polygon shape edited with the gxBreakNeitherEdit flag set2-77
  399. Figure 2-57    A polygon shape edited with the breakLeftEdit flag set2-78
  400. Figure 2-58    A polygons shape edited with the breakRightEdit flag set2-78
  401. Listing 2-31    Creating a path shape with two curved contours2-79
  402. Figure 2-59    A paths shape with two curved contours2-80
  403. Figure 2-60    A path shape edited with GXSetPathParts2-81
  404. Listing 2-32    Creating a path shape with one contour2-81
  405. Figure 2-61    A path shape with a flat top2-82
  406. Figure 2-62    A path shape edited to have a pointy top2-83
  407. Figure 2-63    A paths shape edited to have a round top2-84
  408. Listing 2-33    Creating a diagonal line2-84
  409. Figure 2-64    A diagonal line2-85
  410. Figure 2-65    An edited line2-85
  411. Table 2-1    Shape-related functions that exhibit special behavior with geometric shapess2-87
  412. Chapter 3    Geometric Styles3-1
  413.  
  414. Figure 3-1    Style object with geometric properties highlighted3-6
  415. Figure 3-2    Shared style objects3-7
  416. Figure 3-3    A geometric shape and a typographic shape sharing a style 3-8
  417. Figure 3-4    Effects of the GXPrimitiveShape function3-10
  418. Figure 3-5    Another example of primitive shapes3-11
  419. Figure 3-6    The QuickDraw GX geometric pen3-15
  420. Figure 3-7    Differing pen widths3-16
  421. Figure 3-8    Pixels included in a hairline3-17
  422. Figure 3-9    A geometry with no hairline3-17
  423. Figure 3-10    Pen placement3-19
  424. Figure 3-11    Effect of the auto-inset style attribute3-19
  425. Figure 3-12    Effect of the auto-inset style attribute for a crossed contour3-20
  426. Figure 3-13    Eliminating crossed contours3-20
  427. Figure 3-14    Constraining Shapes to Grids3-22
  428. Figure 3-15    Caps, Joins, Dashes, and Patterns3-23
  429. Figure 3-16        A capped shape3-24
  430. Figure 3-17        Level caps3-24
  431. Figure 3-18            Standard cap shapes3-25
  432. Figure 3-19        A joined shape3-26
  433. Figure 3-20        Level joins3-26
  434. Figure 3-21            Standard joins 3-27
  435. Figure 3-22    Sharp join with miter3-27
  436. Figure 3-23        A dashed shape3-28
  437. Figure 3-24                Scaling a dash shape3-28
  438. Figure 3-25    Effect of the clip-dash dash attribute3-29
  439. Figure 3-26    Effects of breaking a dash3-30
  440. Figure 3-27    Effects of bending a dash3-30
  441. Figure 3-28        A patterned shape3-31
  442. Figure 3-29    Pattern grids3-31
  443. Figure 3-30    Effects of the port-align pattern attribute3-32
  444. Figure 3-31    Effects of the port-map pattern attribute3-32
  445. Figure 3-32    A shape with a cap, join, and pattern3-33
  446. Figure 3-33    A shape with a dash and a pattern3-34
  447. Figure 3-34    A shape with a clipped dash and a cap and join3-35
  448. Listing 3-1    Adding style information by directly manipulating a style object3-36
  449. Figure 3-35    Rectangle with thick pen3-38
  450. Listing 3-2    Manipulating style information indirectly3-38
  451. Listing 3-3    Constraining a shape to a half-inch grid3-39
  452. Figure 3-36    Scaled, but not constrained, V shape3-40
  453. Figure 3-37    Constrained V shape3-41
  454. Listing 3-4    Creating a shape with fractional geometric point positions3-42
  455. Figure 3-38    Rotated star not constrained to device grid (magnified 200 percent)3-42
  456. Figure 3-39    Rotated star constrained to device grid (magnified 200 percent)3-43
  457. Listing 3-5    Converting a circle to a polygon3-44
  458. Figure 3-40    Accurate polygon approximation of a circle3-44
  459. Figure 3-41    Less accurate polygon approximation of a circle3-45
  460. Figure 3-42    Highly inaccurate polygon approximation of a circle3-45
  461. Figure 3-43    Polygon resulting from a curve error of 03-46
  462. Listing 3-6    Creating a complicated contour3-46
  463. Figure 3-44    Wavy line3-47
  464. Figure 3-45    Wavy line somewhat smoothed by curve error of 103-48
  465. Figure 3-46    Wavy line smoothed by curve error of 153-48
  466. Figure 3-47    Wavy line completely straightened by curve error of 203-48
  467. Listing 3-7    Defining a figure eight3-49
  468. Figure 3-48    A hairline figure eight3-49
  469. Figure 3-49    A thick figure eight3-50
  470. Figure 3-50    A figure eight with the pen inset3-50
  471. Figure 3-51    A figure eight with path outset3-51
  472. Figure 3-52    A reversed figure eight with path outset3-52
  473. Listing 3-8    Removing unwanted contour crossings3-52
  474. Figure 3-53    Uncrossed figure eight with pen outset3-53
  475. Listing 3-9    Creating an arrow3-54
  476. Figure 3-54    An arrow3-56
  477. Listing 3-10    Adding round caps and square caps3-57
  478. Figure 3-55    Round and square caps3-58
  479. Listing 3-11    Adding joins to a shape3-58
  480. Figure 3-56    A square with diamond-shaped joins3-60
  481. Figure 3-57    Level joins3-60
  482. Listing 3-12    Adding a sharp join to an angle shape3-61
  483. Figure 3-58    Very sharp join3-62
  484. Figure 3-59    A truncated sharp join3-62
  485. Listing 3-13    Creating a curve shape dashed with diamonds3-63
  486. Figure 3-60    Dashed curve3-65
  487. Figure 3-61     Scaled dashes3-65
  488. Figure 3-62    Clipped dashes3-66
  489. Figure 3-63    Phased dashes3-66
  490. Listing 3-14    Creating a dashes circle3-67
  491. Figure 3-64    Circle dashed with diamonds3-68
  492. Figure 3-65    Automatically advanced dashes3-69
  493. Figure 3-66    Circle with diamond dashes inset3-70
  494. Figure 3-67    Circle with diamond dashes moved toward the center3-71
  495. Figure 3-68    Dash shape with two contours3-71
  496. Listing 3-15    Creating a dash with multiple contours3-72
  497. Figure 3-69    Circle dashed with double diamonds3-73
  498. Figure 3-70    Circle with dashes broken3-73
  499. Figure 3-71    Circle with airline dashes3-74
  500. Figure 3-72    Circle with bent hairline dashes3-75
  501. Listing 3-16    Wrapping text3-75
  502. Figure 3-73    Wrapped text3-76
  503. Listing 3-17    Creating a circle with 12 dashes3-77
  504. Figure 3-74    Dash positions for a clock3-78
  505. Listing 3-18    Creating a clock shape3-79
  506. Figure 3-75    A clock shape3-80
  507. Listing 3-19    Patterning a shape3-81
  508. Figure 3-76    A patterned rectangle3-82
  509. Figure 3-77    Patterning a framed shape3-83
  510. Listing 3-20    Changing a pattern throughout a patterned shape3-83
  511. Figure 3-78    Shape with changing pattern3-85
  512. Listing 3-21    Combining a cap, join, and pattern3-86
  513. Figure 3-79    Angle shape with cap, join, and pattern3-88
  514. Figure 3-80    Shape with dash and pattern; caps and join ignored3-89
  515. Figure 3-81    Shape with cap, join, dash, and the gxClipDash dash attribute set3-90
  516. Chapter 4    Geometric Operations4-1
  517.  
  518. Figure 4-1    Line contours4-4
  519. Figure 4-2    A path shape with two contours4-5
  520. Figure 4-3    A path shape with two contours4-5
  521. Figure 4-4    A path whose contour direction is not immediately obvious4-6
  522. Figure 4-5    A path whose inner contour has the same contour direction as its outer contour4-7
  523. Figure 4-6    A path shape whose inner and outer contours have different contour direction4-7
  524. Figure 4-7    Effects of reducing and simplifying shape geometries4-9
  525. Figure 4-8    How simplifying a shape can produce more predictable results when drawing4-10
  526. Figure 4-9    Simple example of the GXPrimitiveShape function4-11
  527. Figure 4-10    More involved example of the GXPrimitiveShape function4-13
  528. Figure 4-11    Geometric information available about a path shape4-15
  529. Figure 4-12    A path shape resized by changing its bounding rectangle4-16
  530. Figure 4-13    Testing shapes for intersection4-17
  531. Figure 4-14    Testing whether one shape contains another4-18
  532. Figure 4-15    Geometric arithmetic with two filled shapes4-19
  533. Figure 4-16    Geometric arithmetic with a framed shape and a filled shape4-20
  534. Figure 4-17    Geometric inversion4-20
  535. Listing 4-1    Creating a polygon shape with two contours having opposite contour directions4-22
  536. Figure 4-18    A polygon shape whose two contours have opposite contour directionsr4-23
  537. Figure 4-19    A polygon shape with the direction of both contours reversed4-24
  538. Figure 4-20    A polygon shape with the direction of the inner contour reversed4-24
  539. Listing 4-2    Creating a path shape with a single contour4-25
  540. Figure 4-21    A path shape with a single contour4-26
  541. Figure 4-22    A path shape broken into two contours4-26
  542. Listing 4-3    Creating a polygon with redundant geometric points4-27
  543. Figure 4-23    A polygon shape with unnecessary geometric points4-28
  544. Figure 4-24    A poygon shape with the unnecessary geometric points removed4-29
  545. Listing 4-4    Creating a polygon shape with a crossed contour4-30
  546. Figure 4-25    A polygon shape with a crossed contour4-30
  547. Figure 4-26    A polygon shape with no crossed contours4-31
  548. Listing 4-5    Creating a path with two clockwise contours4-31
  549. Figure 4-27    A path shape with two concentric clockwise contours4-32
  550. Figure 4-28    A path shape with two concentric contours with opposite contour direction4-32
  551. Figure 4-29    A path shape with two concentric clockwise contours drawn with winding shape fill4-33
  552. Figure 4-30    A path shape simplified to a single clockwise contour4-33
  553. Listing 4-6    Creating an hourglass polygon shape with a thick pen width4-34
  554. Figure 4-31    A hourglass-shaped polygon with a thick border4-35
  555. Figure 4-32    A polygon shape with style information incorporated into its geometry4-35
  556. Figure 4-33    The primitive form of the polygon shape after simplification4-36
  557. Listing 4-7    Creating a pathshape with two contours having opposite contour directions4-37
  558. Figure 4-34    A path with an outer clockwise contour and an inner counterclockwise contour4-37
  559. Figure 4-35    A specified point on a path contour4-38
  560. Figure 4-36    Finding the bounding rectangle and the centerpoint of a path4-39
  561. Figure 4-37    Finding the center point of two contours4-40
  562. Figure 4-38    Finding the area of a shape4-40
  563. Figure 4-39    The sum of all the contour areas of a path shape4-41
  564. Figure 4-40    A simplified path4-42
  565. Listing 4-8    Creating a circular path4-42
  566. Figure 4-41    A circular path4-43
  567. Figure 4-42    A smaller circular path4-44
  568. Figure 4-43    A path shape with a transform mapping4-45
  569. Listing 4-9    Creating a tight curve shape4-45
  570. Figure 4-44    A tight curve4-46
  571. Figure 4-45    An inset curve shape  with 16 geometric points4-46
  572. Figure 4-46    An outset curve4-47
  573. Listing 4-10    Creating a rectangle and a circular path shape4-48
  574. Figure 4-47    A rectangle containing a circular path4-48
  575. Figure 4-48    A rectangle that touches a circular path shape4-49
  576. Figure 4-49    A rectangle and a circular path touching at a single point4-50
  577. Figure 4-50    A large circular path shape touching a smaller circular path shape4-51
  578. Listing 4-11    Creating a donut-shaped path and a smaller, concentric path4-51
  579. Figure 4-51    A path shape with two contours and a smaller concentric rectangle shape4-53
  580. Listing 4-12    Creating a diamond-shaped polygon and a circlular path that intersect4-54
  581. Figure 4-52    A diamond-shaped polygon geometry and a circular path geometry4-55
  582. Figure 4-53    The intersection of a diamond-shaped polygon and a circular path4-55
  583. Figure 4-54    The union of a diamond-shaped polygon and a circular path4-56
  584. Figure 4-55    The union of a framed diamond-shaped polygon and a circular path4-57
  585. Figure 4-56    The result of subtracting a circular path from a diamond-shaped polygon4-57
  586. Figure 4-57    The result of subtracting a diamond-shaped polygon from a circular path4-58
  587. Figure 4-58    The result of the exclusive-or operation on a polygon and a path4-59
  588. Figure 4-59    An inverted diamond 4-59
  589. Chapter 5    Bitmap Shapes5-1
  590.  
  591. Figure 5-1    A bitmap shape5-4
  592. Figure 5-2    A black-and-white bitmap geometry5-6
  593. Figure 5-3    A grayscale bitmap geometry5-6
  594. Figure 5-4    The effect of transfer modes on bitmap shapes5-8
  595. Figure 5-5    The effect of mappings on bitmap shapes5-9
  596. Figure 5-6    The effect of the gxMapTransformShape shape attribute on bitmap mappings 5-10
  597. Figure 5-7    Bitmaps and view devices5-12
  598. Listing 5-1    Creating a black-and-white bitmap5-14
  599. Figure 5-8    A black-and-white bitmap—32 bits wide5-15
  600. Figure 5-9    An example of unaligned bytes per row5-18
  601. Listing 5-2    A bit image with an even number of bytes per row5-18
  602. Figure 5-10    An envelope with a shadow5-19
  603. Figure 5-11    A thinner envelope bitmap with four shades of grey5-20
  604. Figure 5-12    A bitmap with sixteen shades of gray5-21
  605. Listing 5-3    Defining a color set5-21
  606. Figure 5-13    A bitmap with eight colors5-22
  607. Listing 5-4    Creating a color ramp5-24
  608. Figure 5-14    A color ramp from red to green5-26
  609. Listing 5-5    Creating a color ramp using the ramp library5-26
  610. Listing 5-6    Creating a color ramp using both the ramp and color libraries5-27
  611. Figure 5-15    Dithered bitmaps5-29
  612. Listing 5-7    Halftoning a bitmap5-29
  613. Figure 5-16    Halftoned bitmaps5-30
  614. Listing 5-8    Applying a transfer mode to a bitmap5-30
  615. Figure 5-17    A blended color ramp5-31
  616. Listing 5-9    Converting a path to a bitmap5-32
  617. Figure 5-18    A bitmap representation of a path shape5-33
  618. Figure 5-19    A bitmap and its bounding rectangle5-33
  619. Figure 5-20    A bitmap drawn over a background5-34
  620. Figure 5-21    A bitmap with a transfer mode drawn over a background5-35
  621. Figure 5-22    A  path shape converted to a bitmap shape5-36
  622. Figure 5-23    A path shape converted to a bitmap shape and then skewed5-36
  623. Figure 5-24    A color ramp bitmap5-37
  624. Figure 5-25    A bitmap after multiple transformations5-37
  625. Listing 5-10    Scaling text5-38
  626. Figure 5-26    Scaled text5-38
  627. Listing 5-11    Scaling a bitmap5-38
  628. Figure 5-27    Scaled text and a scaled bitmap5-39
  629. Figure 5-28    A clipped bitmap5-40
  630. Listing 5-12    Creating a black-and-white bitmap that uses QuickDraw GX memory5-43
  631. Listing 5-13    Creating an offscreen bitmap5-46
  632. Figure 5-29    Multiple shapes drawn to a bitmap5-47
  633. Listing 5-14    Creating an offscreen bitmap using the offscreen library5-47
  634. Figure 5-30    An extracted bitmap5-49
  635. Figure 5-31    An editied bitmap 5-50
  636. Table 5-1    Geometry-related functions that post errors or warnings when applied to bitmaps5-52
  637. Table 5-2    Geometric operations that post errors or warnings when applied to bitmaps5-52
  638. Table 5-3    Shape-related functions that exhibit special behavior when applied to bitmaps5-53
  639. Table 5-4    Geometric operations that exhibit special behavior when applied to bitmaps5-54
  640. Table 5-5    Transform-related functions that exhibit special behavior when applied to bitmaps5-56
  641. Table 5-6    View-related functions that can be applied to bitmaps5-57
  642. Chapter 6    Picture Shapes6-1
  643.  
  644. Figure 6-1    A picture shape6-4
  645. Figure 6-2    A picture item6-5
  646. Figure 6-3    A picture geometry with two items6-6
  647. Figure 6-4    Condensed picture with two items6-7
  648. Figure 6-5    A picture shape with overrides6-8
  649. Figure 6-6    A picture containing multiple references to the same shape6-9
  650. Figure 6-7    A picture item6-10
  651. Figure 6-8    Multiple references with overriding transforms6-11
  652. Figure 6-9    Multitple references with overriding styles, inks, and transforms6-12
  653. Figure 6-10    Adding shapes to a picture without the unique items attribute6-13
  654. Figure 6-11    Adding shapes to a picture with the unique items attribute6-14
  655. Figure 6-12    A condensed view of a picture hierarchy6-15
  656. Figure 6-13    A path shape and its transform6-16
  657. Figure 6-14    A picture with an overriding transform6-17
  658. Figure 6-15    Simple transform concatenation6-18
  659. Figure 6-16    Intricate transform concatenation6-19
  660. Figure 6-17    A picture shape and its transform6-21
  661. Listing 6-1    Creating a simple picture of a house6-23
  662. Figure 6-18    A picture of a house with a roof and a door6-25
  663. Listing 6-2    Disposing of shapes contained in a picture before disposing of the picture6-26
  664. Listing 6-3    Extracting and editing items from a picture6-27
  665. Figure 6-19    A picture of a house with a relocated door6-28
  666. Listing 6-4    Defining new shapes for the house picture6-28
  667. Listing 6-5    Adding new shapes to the house picture6-29
  668. Figure 6-20    A house with a lawn, walkway, and chimney6-30
  669. Listing 6-6    Removing an item from a picture6-31
  670. Figure 6-21    A house with chimney removed6-31
  671. Listing 6-7    Replacing one shape with another6-32
  672. Figure 6-22    A house with the chimney replaced6-32
  673. Listing 6-8        Creating style, ink, and transform objects6-33
  674. Listing 6-9    Creating a picture whose items have overriding styles, inks, and transforms6-34
  675. Listing 6-10    Disposing of overriding style, ink, and transform objects before drawing6-35
  676. Figure 6-23    A house picture with an overriding style, ink, and transform6-35
  677. Listing 6-11    Adding four items to a house picture that reference the same shape6-36
  678. Listing 6-12    Disposing of the white rectangle and the three transform objects before drawing6-37
  679. Figure 6-24    A house with four windows6-37
  680. Listing 6-13    Adding unique items to a picture6-38
  681. Figure 6-25    A house with four windows and four unique overriding transforms6-39
  682. Listing 6-14        Creating a picture hierarchy6-39
  683. Figure 6-26    A house rotated by 90 degrees two times6-40
  684. Listing 6-15    Creating a picture hierarchy6-41
  685. Figure 6-27    Grounds picture6-42
  686. Figure 6-28    House picture6-42
  687. Figure 6-29    Picture containing grounds picture and house picture6-43
  688. Listing 6-16    Hit-testing a picture shape6-44
  689. Figure 6-30    Hit-testing the picture of house and grounds6-44
  690. Table 6-1    Hit-testing a picture at different levels and depths6-44
  691. Table 6-2    Geometric operations that post errors or warnings when applied to pictures6-46
  692. Table 6-3    Shape-related functions that exhibit special behavior when applied to pictures6-48
  693. Table 6-4    Geometric operations that exhibit special behavior when applied to pictures6-48
  694. About This Book
  695.  
  696.  
  697. QuickDraw GX is an integrated, object-based approach to graphics programming on Macintosh computers. This book, Inside Macintosh: QuickDraw GX Graphics, describes the data types and functions you use to create graphic images.
  698. For application programming purposes, QuickDraw GX replaces the capabilities of some of the Macintosh system software managers documented in other parts of Inside Macintosh. Information in this book replaces the information in all chapters of Inside Macintosh: Imaging With QuickDraw.
  699. Before you read this book, you should already be familiar withinformation described elsewhere in the Inside Macintosh: QuickDraw GX books before you read this book. In particular,
  700. n    For a rivetting overview of the entire QuickDraw GX architecture, and a compelling introduction to programming with QuickDraw GX, you should readthe free-spirited and frollicking tome Getting Started With QuickDraw GX.
  701. n    You should, at the very least, have read the information about QuickDraw GX shapes and objects in the chapter  “Introduction to QuickDraw GX” in Inside Macintosh: QuickDraw GX Objects. You should also read the chapter “Shape Objects” in that book.
  702. n    Before you read Chapter 3, “Geometric Styles,” in this book, you should read the chapter “Style Objects” in Inside Macintosh: QuickDraw GX Objects.
  703. n    As you read this chapter and the other chapters in this book, you might want to be familiar with the other information in Inside Macintosh: QuickDraw GX Objects—in particular, you might also read the “Ink Objects,” and “Transform Objects” chapters in that book.
  704.  
  705. What to Read
  706.  
  707. This chapter introduces three types of QuickDraw GX shapes you can use to make graphic images:
  708. n    geometric shapes
  709. n    bitmap shapes
  710. n    picture shapes
  711. The other types of QuickDraw GX shapes (the typographic shapes) are discussed in Inside Macintosh: QuickDraw GX Typography.
  712. Geometric shapes are the building blocks for graphics. These shapes, which include points, lines, curves, rectangles, polygons, and paths, make up the graphic elements supported by most drawing programs. The chapter “Geometric Shapes” in this book describes geometric shapes in detail. The chapter “Geometric Styles” in this book describes the stylistic variations you can make to geometric shapes. The chapter “Geometric Operations” in this book describes the functions you can use to manipulate geometric shapes and obtain geometric information about them.
  713. Bitmap shapes contain pixel images. These shapes allow you to create graphics by specifying the color value of each pixel in the image. The chapter “Bitmap Shapes” in this book describes bitmap shapes in detail. This chapter also references a number of the color plates you can find at the front of this book.
  714. Picture shapes are collections of QuickDraw GX shapes, including other picture shapes. You can find this type of shape described in the chapter “Picture Shapes,” in this book.
  715.  
  716. Chapter Organization
  717.  
  718. Most chapters in this book follow a standard general structure. For example, the chapter “Geometric Shapes” contains these major sections:
  719. n    “About Geometric Shapes.” This sections provides an overview of geometric shapes.
  720. n    “Using Geometric Shapes.” This section describes how you can create and manipulate geometric shapes using QuickDraw GX. It describes how to use the most common functions, gives related user interface information, provides code samples, and supplies additional information.
  721. n    “Geometric Shapes Reference.” This section provides a complete reference to geometric shapesgeometric shapes by describing the constants, data types, and functions that you use with geometric shapes. Each function description follows a standard format, which gives the function declaration; a description of every parameter; the function result, if any; and a list of errors, warnings, and notices. Most function descriptions give additional information about using the function and include cross-references to related information elsewhere.
  722. n    “Summary of Geometric Shapes.” This shows the C interface for the constants, data types, and functions associated with geometric shapes.
  723.  
  724. Conventions Used in This Book
  725.  
  726. This book uses various conventions to present certain types of information.
  727. Special Fonts
  728.  
  729. All code listings, reserved words, and the names of data structures, constants, fields, parameters, and functions are shown in Courier (this is Courier).
  730. When new terms are introduced, they are in boldface. These terms are also defined in the Glossary.
  731. Types of Notes
  732.  
  733. There are several types of notes used in this book. 
  734. Note
  735. A note formatted like this contains information that is interesting but possibly not essential to an understanding of the main text. The wording in the tag may say something more descriptive than just “Note,” for example “Terminology Note.”u
  736. IMPORTANT
  737. A note like this contains information that is especially important.s
  738. sWARNING
  739. Warnings like this indicate potential serious problems that you should be aware of as you design your application. Failure to heed these warnings could result in system crashes and loss of data.s
  740. Numerical Formats
  741.  
  742. Hexadecimal numbers are shown in this format: 0x008.
  743. The numerical values of constants are shown in decimal, unless the constants are flag or mask elements that can be summed, in which case they are shown in hexadecimal.
  744. Illustrations
  745.  
  746. The following conventions are used in illustrations in this book.
  747. In illustrations that show object properties, properties that are object references are in italics.
  748. In order to focus attention on the key part of some drawings, other parts are printed in gray, rather than black.
  749. This book also uses other conventions for representing shape objects, style objects, ink objects, and transform objects. You can find examples in Figure 1-1, Figure 1-3, and Figure 1-5 in Chapter 1, “Introduction to QuickDraw GX Graphics.”
  750.  
  751.  
  752. Development Environment
  753.  
  754. The QuickDraw GX functions described in this book are available using C interfaces. How you access these functions depends on the development environment you are using.
  755. Code listings in this book are shown in ANSI C. They suggest methods of using various functions and illustrate techniques for accomplishing particular tasks. Although most code listings have been compiled and tested, Apple Computer, Inc., does not intend for you to use these code samples in your applications.
  756.  
  757. Developer Products and Support
  758.  
  759. APDA is Apple’s worldwide source for over three hundred development tools, technical resources, training products, and information for anyone interested in developing applications on Apple platforms. Customers receive the quarterly APDA Tools Catalog featuring all current versions of Apple development tools and the most popular third-party development tools. Ordering is easy; there are no membership fees, and application forms are not required for most of our products. APDA offers convenient payment and shipping options, including site licensing.
  760. To order products or to request a complimentary copy of the APDA Tools Catalog, contact 
  761. APDA 
  762. Apple Computer, Inc. 
  763. P.O. Box 319
  764. Buffalo, NY 14207-0319Telephone    800-282-2732 (United States)
  765. 800-637-0029 (Canada)
  766. 716-871-6555 (International)    
  767. Fax    716-871-6511     
  768. AppleLink    APDA    
  769. America Online    APDA    
  770. CompuServe    76666,2405    
  771. Internet    APDA@applelink.apple.com    
  772.         
  773. If you provide commercial products and services, call 408-974-4897 for information on the developer support programs available from Apple.
  774. Listing 1-0
  775. Table 1-0
  776. Introduction to QuickDraw GX Graphics
  777. Contents
  778. About QuickDraw GX Graphics1-3
  779. Geometric Shapes1-6
  780. Geometric Shape Types1-6
  781. Geometric Shape Geometries1-7
  782. Geometric Shape Fills1-8
  783. Geometric Styles, Inks, and Transforms1-9
  784. Geometric Operations1-11
  785. Bitmap Shapes1-15
  786. Picture Shapes1-17
  787. Introduction to QuickDraw GX Graphics
  788. This chapter introduces three types of QuickDraw GX shapes you can use to make graphic images:
  789. n    geometric shapes
  790. n    bitmap shapes
  791. n    picture shapes
  792. The other types of QuickDraw GX shapes (the typographic shapes) are discussed in Inside Macintosh: QuickDraw GX Typography.
  793. You should be familiar with information described elsewhere in the Inside Macintosh: QuickDraw GX books before you read this book. In particular,
  794. n    You should read the information about QuickDraw GX shapes and objects in the chapter  “Introduction to QuickDraw GX” in Inside Macintosh: QuickDraw GX Objects. You should also read the chapter “Shape Objects” in that book.
  795. n    Before you read Chapter 3, “Geometric Styles,” in this book, you should read the chapter “Style Objects” in Inside Macintosh: QuickDraw GX Objects.
  796. n    As you read this chapter and the other chapters in this book, you might want to be familiar with the other information in Inside Macintosh: QuickDraw GX Objects—in particular, you might also read the “Ink Objects,” and “Transform Objects” chapters in that book.
  797. This chapter, which introduces the main concepts found in the rest of this book, starts by reviewing the objects that make up a QuickDraw GX shape and by introducing the different types of graphic shapes. It then provides a brief discussion of
  798. n    the structure of the geometric shapes
  799. n    the contents of geometric shape geometries
  800. n    the shape fill property and how it affects geometric shapes
  801. n    the properties of the style object that modify geometric shapes
  802. n    the geometric operations provided by QuickDraw GX
  803. n    the structure of bitmap shapes
  804. n    the structure of picture shapes
  805.  
  806. About QuickDraw GX Graphics
  807.  
  808. With QuickDraw GX, you create graphics by creating QuickDraw GX shapes. Graphic shapes include geometric shapes, bitmap shapes, and picture shapes:
  809. n    Geometric shapes are the building blocks for graphics. These shapes, which include points, lines, curves, rectangles, polygons, and paths, make up the graphic elements supported by most drawing programs. There are also two special types of geometric shapes: empty shapes, which cover no area, and full shapes, which cover all area.
  810. n    Bitmap shapes contain pixel images. These shapes allow you to create graphics by specifying the color value of each pixel in the image.
  811. n    Picture shapes are collections of QuickDraw GX shapes, including other picture shapes.
  812. All QuickDraw GX shapes share the same basic structure. They are all represented by a shape object and its associated style, ink, and transform objects. Figure 1-1 shows the structure of the objects that represent a QuickDraw GX shape.
  813. Figure 1-1    Shape object structure
  814.  
  815. Figure 1-1 shows the four basic QuickDraw GX objects and lists the properties of each. This figure includes all of the properties of these objects. However, this book examines only a subset of these properties. Properties not examined in this book are greyed out.
  816. Like asll shapes, geometric shapes are represented by a shape object in memory. Three of the properties of the shape object—shape type, shape geometry, and shape fill—and how they apply to geometric shapes in particular, are introduced in section “Geometric Shapes” beginning on page 1-6 and are fully discussed in the “Geometric Shapes” chapter of this book.
  817. Geometric shapes also use the style object properties highlighted in Figure 1-1. These properties are introduced in the section “Geometric Styles, Inks, and Transforms” beginning on page 1-9 and are fully examined in the “Geometric Styles” chapter of this book.
  818. Geometric shapes also use the properties of their ink and transform objects. You can find more information about these objects in the chapters “Ink Objects” and “Transform Objects” in Inside Macintosh: QuickDraw GX Objects.
  819. Bitmap shapes also use their shape, style, ink, and transform objects, although they make limited use of some of the properties of these objects. Bitmap shapes are introduced in the section “Bitmap Shapes” beginning on page 1-15 and are fully examined in the chapter “Bitmap Shapes” in this book.
  820. Picture shapes shapes also use their shape, style, ink, and transform objects, although like bitmaps they make limited use of some of the properties of these objects. Picture shapes are introduced in the section “Picture Shapes” beginning on page 1-17 and are fully examined in the chapter “Picture Shapes” in this book.
  821. QuickDraw GX allows you to convert between the different types of shapes. Table 1-1 describes where to look in each book for information regarding each possible kind of conversion.
  822. Table 1-1    Where to find information on shape-type conversion
  823. To convert:
  824.       …to a 
  825. geometric shape    …to a 
  826. bitmap shape    …to a 
  827. picture shape    …to a 
  828. typographic shape    
  829. from a geometric shape…    See “Geometric Shapes” in this book    See “Bitmap Shapes” in this book    See “Picture Shapes” in this book    
  830. (not possible)    
  831. from a bitmap shape…    
  832. (not possible)
  833.     See “Bitmap Shapes” in this book    See “Picture Shapes” in this book    
  834. (not possible)    
  835. from a picture shape…    
  836. (not possible)
  837.     See “Bitmap Shapes” in this book    See “Picture Shapes” in this book    
  838. (not possible)    
  839. from a typographic shape…    See “Typographic Shapes” in QuickDraw GX Typography    See “Bitmap Shapes” in this book    See “Picture Shapes” in this book    See “Typographic Shapes” in QuickDraw GX Typography    
  840.  
  841.  
  842.  
  843. Geometric Shapes
  844.  
  845. QuickDraw GX provides six types of geometric shapes—the basic building blocks of QuickDraw GX graphics. These shapes includes points, lines, rectangles, curves, polygons, and paths. You can use these shapes for drawing, for calculating areas, for clipping, as elements of more complex graphics, and so on. 
  846. As with all types of QuickDraw GX shapes, a geometric shape is represented by a shape object in QuickDraw GX memory. However, what defines a geometic shape—what makes it different from other types of shapes—is how it uses the properties of the shape object:
  847. n    The shape type property specifies the type of the geometric shape—empty, full, point, line, curve, rectangle, polygon, or path.
  848. n    The geometry property specifies the positions of the points that define the shape—for example, the end points of a line, or the corners of a rectangle
  849. n    The shape fill property specifies how the geometry of the shape is interpreted—for example, as a framed outline or as a solid area
  850. n    The style property references a style object, which specifies modifications to the geometric shape—for example, pen width, dashes, and patterns.
  851. n    The ink and transform properties reference an ink and a transform object. The ink object specifes the color and transfer mode applied to the shape when drawn. The transform object specifies mapping transformations made to the shape, how the shape is clipped, how the shape is hit-tested, and to what view ports the shape is finally drawn.
  852. n    The attributes, owner count, and tag list properties contain object-related information about the shape. These properties affect how the shape object is maintained in memory, when the memory held by the shape is freed, and other information you might want to specify for a particular shape.
  853. Geometric shapes use all of the shape properties—to understand geometric shapes fully, you should be familiar with all of these properties, which are introduced in the “Shape Objects” chapter of Inside Macintosh: QuickDraw GX Objects. The way that geometric shapes use these properties differently from other types of shapes is described in this book, particularly in the “Geometric Shapes” and “Geometric Styles” chapters.
  854. Geometric Shape Types
  855.  
  856. There are six basic types of geometric shapes: points, lines, rectangles, curves, polygons, and paths. Figure 1-2 lists these shape types and also shows a sample geometry for each of them. Each geometry is made up of geometric points and edges that connect the geometric points. The next section, “Geometric Shape Geometries,” introduces these concepts in more detail.
  857. Figure 1-2    The geometric shape types and examples of geometric shape geometries
  858.  
  859. There are two types of geometric shapes not listed in this figure: the empty shape and the full shape. An empty shape is a shape that has no geometry and covers no area. A full shape is the inverse of an empty shape—it covers all area.
  860. Geometric Shape Geometries
  861.  
  862. Each type of geometric shape uses the geometry property of its shape object in a slightly different manner. For example, empty shapes and full shapes store no information in their geometry, because they require no further geometric information—their shape type says it all.
  863. However, for other types of geometric shapes, the shape type does not contain all the geometric information necessary to define the shape. The geometries of these shapes contain x-coordinate/y-coordinate pairs called geometric points—points that specify the location, dimension, and form of the geometric shapes:
  864. n    Point geometries contain one geometric point—an x-coordinate and a y-coordinate—to specify the position of the point shape.
  865. n    Line geometries contain two geometric points—one point to specify where the line starts and one to specify where the line ends.
  866. n    Rectangle geometries also contain two geometric points—specifying the position of opposing corners of the rectangle.
  867. n    Curve shapes store three geometric points in their geometry—one to specify where the curve starts, another to specify where the curve ends, and another, called the off-curve control point, to specify the tangents used to define the curve.
  868. n    Polygon geometries are made up of 0, 1, or more polygon contours. Each polygon contour is series of geometric points connected by straight lines.
  869. n    Path geometries are similiar to polygon geometries, although path geometries also store information about which geometric points are on-curve and which are off-curve control points. Therefore, path contours can have curved edges as well as straight edges.
  870. As an example, Figure 1-2 shows a polygon shape with a single polygon contour made up of three geometric points. This figure shows three views of the polygon geometry: as a list of x-coordinate/y-coordinate pairs, as three geometric points plotted on a geometric grid, and as three points connected by three straight lines. This third way of viewing geometries is used frequently throughout this book, as it shows not only the geometric points, but also the implied edges that connect them.
  871. Figure 1-3    A polygon shape with a single polygon contour containing three geometric points
  872.  
  873. Geometric Shape Fills
  874.  
  875. The shape fill property specifies how QuickDraw GX interprets the geometric points of a geometric shape’s geometry. There are two basic types of shape fills:
  876. n    Framed fills. These shape fills indicate that QuickDraw GX should interpret the shape as an outline—as a series of edges.
  877. n    Solid fills. These shape fills indicate that QuickDraw GX should interpret the shape as a solid area—the edges of the shape represent the boundaries of the area.
  878. Figure 1-2 shows an example of a polygon contour similar to the one in Figure 1-2, and how QuickDraw GX might draw it with a framed fill and with a solid fill.
  879. Figure 1-4    Framing shapes versus filling shapes
  880.  
  881. For more information about these and the other shape fills provided by QuickDraw GX, see the chapter “Geometric Shapes” in this book.
  882. Geometric Styles, Inks, and Transforms
  883.  
  884. Like all QuickDraw GX shapes, geometric shapes reference a style object, an ink object, and a transform object. Figure 1-6 shows a condensed view of how a polygon shape might use these four objects. 
  885. Instead of listing every property of each of these objects, the first half of Figure 1-6 (the left side) depicts a single important property for each object:
  886. n    For the shape object, it shows the polygon geometry. 
  887. n    For the style object, it shows the pen width.
  888. n    For the ink object, it shows the color,
  889. n    For the transform object, it shows the transformation mapping. 
  890. This condensed view of these objects is used frequently throughout this book, as it highlights information important to a particular example.
  891. The second half of Figure 1-6 (the right side) shows an even more condensed of the polygon shape. In this view, all of the stylistic, color, and transform variations have been incorporated into the shape itself—basically showing the shape as it is drawn. This extremely condensed view is used occasionally throughout this book, particularly when many shapes must appear in a single figure, as in the chapter “Picture Shapes.”
  892. Figure 1-5    Two condensed views of a polygon shape
  893.  
  894. Geoemtric shapes use the properties of their ink and transform objects in the same way that typographic shapes do. For example, you can apply a color to a geometric shape, or rotate a geometric shape, in the same way that you would for a typographic shape. Because these objects apply equally to geometric and typographic shapes, they are discussed in Inside Macintosh: QuickDraw GX Objects, rather than in this book.
  895. However, geometric shapes use the properties of their style objects in a very different way than typographic shapes do. 
  896. The style object has three types of properties: 
  897. n    Object-related style properties, which are discussed in the chapter “Style Objects” in Inside Macintosh: QuickDraw GX Objects. These properties apply to the style as an object in memory.
  898. n    Typographic style properties, which are discussed in the chapter “Typographic Styles” in Inside Macintosh: QuickDraw GX Typography. These properties apply only to typographic shapes.
  899. n    Geometric style properties, which are discussed in the chapter “Geometric Styles” in this book. These properties apply primarily to geometric shapes.
  900. The geometric style properties are the properties of the style object that specify modifications to geometric shapes. With these properties, you can specify how wide QuickDraw GX should draw a shape’s edges, whether the edges should be solid or dashed, whether corners should be round or sharp, what pattern should fill a shape’s area, and so on.
  901. Figure 1-6 shows the geometric properties of the style object. This figure also gives examples of the effects of these properties.
  902. Figure 1-6    The geometric style properties and some examples of their effects
  903.  
  904. You can find more information about these stylistic modifications in the “Geometric Styles” chapter of this book.
  905. Geometric Operations
  906.  
  907. QuickDraw GX provides many functions that allow you to modify the geometries of geometric shapes, obtain information about their geometries, and combine the geometries of two shapes. 
  908. One such geometric operations allows you to remove unnecessary or redundant geometric points from the shape’s geometry—this process is called reducing a geometry.
  909. Figure 1-7 shows a polygon geometry with two unneccesary geometric points:
  910. n    Point 2 lies on the same line as points 1 and 3, and therefore has no effect on the geometry.
  911. n    Points 4 and 5 lie over one another, and so only one is necessary for this geometry.
  912. Figure 1-7    An example of eliminating unnecessary geometric points from a shape 
  913.  
  914. In addition to unnecessary geometric points, a shape geometry can have a number of other complicating qualities, such as crossed edges or overlapping contours. QuickDraw GX provides a geometric operation which redefines a shape’s geometry to eliminate these qualities. This process is called simplifying a shape. Figure 1-7 shows a polygon contour with two edges that cross and the result of simplifying this shape.
  915. Figure 1-8    An example of simplifying a shape
  916.  
  917. As Figure 1-7 shows, simplifying the polygon geometry splits it into two contours: an upper, triangular, contour with three geometric points, and a lower triangular contour with three geometric points. Although the simplified geometry contains more geometric points and more contours than the original, it does not contain any crossed edges.
  918. You can find more about reducing and simplifying shape geometries in the “Geometric Operations” chapter of this book. That chapter also describes many functions that allow you to obtain information about geometric shapes and perform geometric arithmetic on them. Figure 1-9 shows some examples of the different types of geometric information that QuickDraw GX calculates for you.
  919. Figure 1-9    Some examples of the geometric information available about a shape
  920.  
  921. You can find more about geometric information in the “Geometric Operations” chapter of this book.
  922. Another important type of geometric operation is geometric arithmetic, such as calculating the union or intersection of two shapes. Figure 1-10 shows some examples of geometric arithmetic. This figure shows the intersection, union, difference, reverse difference, and exclusion operations, which each return a different result calcuated by combining the geometries of two shapes in different ways.
  923. Figure 1-10    Some examples of the geometric arithmetic you can perform with shapes
  924.  
  925. Other geometric operations provided by QuickDraw GX allow you to
  926. n    alter the order of the geometric points specified in a shape’s geometry
  927. n    break a single shape contour into multiple contours
  928. n    calculate whether two shapes intersect
  929. n    calculate whether one shape contains another shape
  930. n    inset the geometric points of a shape’s geometry
  931. n    scale the shape to fit in a new bounding rectangle
  932. n    invert the geometry of a shape
  933. These geometric operations are all discussed in the “Geometric Operations” chapter of this book.
  934. The chapter “Transform Objects” in Inside Macintosh: QuickDraw GX Objects describes a related set of functions you can use to perform geometric modifications to a shape’s geometry. These functions allow you to 
  935. n    move a shape
  936. n    rotate a shape
  937. n    scale a shape
  938. n    skew a shape
  939. n    perform any arbitrary mapping on a shape
  940. Depending on the setting of a shape’s map-transform shape attribute, these functions either modify the mapping matrix contained in the shape’s transform object or recalculate the geoemtric points contained in the shape’s geometry directly.
  941.  
  942.  
  943. Bitmap Shapes
  944.  
  945. Bitmap shapes allow you to create images for which you specify the color value of each pixel. Geometric shapes create images with more flexibility—they can be rendered by QuickDraw GX accurately at any output device resolution. However, you might still want to use bitmap shapes for a number of reasons. For example, if you know the resolution of an output device, you can create a bitmap shape to use as an offscreen graphics buffer. As another example, since bitmaps allow you to specify multiple colors within a single shape, you can use bitmaps to create gradients or ramps—shapes that fade from one color to another.
  946. Figure 1-11 shows some sample bitmaps.
  947. Figure 1-11    Sample bitmap shapes
  948.  
  949. Although there are many types of geometric shapes—points, lines, curves, and so on—there is only one type of bitmap shape. Bitmap shapes make extensive use of their geometry property. In fact, most of the information useful to bitmap shapes is stored in their geometry—the values of the bitmap’s pixels, the dimensions of the bitmap, and the color information used by the bitmap. 
  950. Bitmap shapes don’t make much use of their shape fill property, and they use very little of their associated style object. In fact, the only information in a style object used by bitmap shapes are the style attributes that determine whether the upper-left corner of the bitmap should be constrained to an integer grid position.
  951. Bitmap shapes don’t use the color property of their ink object, as they store their own color information in their geometries. However, they do use the transfer mode property of their ink objects.
  952. Bitmap shapes do make full use of their transform objects, however. For example, you can scale, skew, rotate, and clip bitmap shapes. You can also hit-test bitmap shapes, but you cannot hit-test parts of a bitmap shape, as you can for other types of shapes. For more information about transform objects and hit-testing, see the chapter “Transform Objects” of Inside Macintosh: QuickDraw GX Objects.
  953. Figure 1-12 shows a bitmap shape object and bitmap geometry.
  954. Figure 1-12    A bitmap shape 
  955.  
  956. As Figure 1-12 shows, a bitmap geometry contains a reference to a pixel image, which contains the color values of each pixel in the bitmap. QuickDraw GX allows pixel images to be stored in three locations:
  957. n    in memory allocated by your application
  958. n    in memory allocated and managed by QuickDraw GX
  959. n    in a disk file
  960. Each of these options presents different advantages and disadvantages. For example, storing a pixel image in a disk file allows you to have large bitmaps without keeping the entire pixel image in memory. However, QuickDraw GX provides only limited access to this type of pixel image: it can read the image, but not make changes to it.
  961. Different bitmap shapes may reference the same pixel image. You might want to use this feature to draw the same pixel image with two different transfer modes, for example, or to draw the same pixel image in two different color spaces.
  962. The other fields of a bitmap geometry define the position, color information, and dimensions of the bitmap’s pixel image. Figure 1-13 shows an example bitmap geometry that uses one bit to represent each pixel, and has four rows and ten columns. Since each row of the pixel image only requires ten bits, the pixel image is padded so that each row is represented by an even number of bytes.
  963. Figure 1-13    Elements of a bitmap geometry
  964.  
  965. The color space and color set fields of the bitmap geometry allow you to specify how QuickDraw GX should interpret the pixel values. In this example, pixel values of 0 represent white pixels and pixel values of 1 represent black pixels. 
  966. (*** I’ve gotten conflicting information about which is the default. Please help. ***)
  967. The color profile field specifies color-matching information. See the “Color-Related Objects” chapter of Inside Macintosh: QuickDraw GX Objects for more information about color values, color spaces, color sets, and color matching.
  968. For more information about bitmap shapes, see the “Bitmap Shapes” chapter of this book.
  969.  
  970. Picture Shapes
  971.  
  972. Picture shapes contain collections of other shapes. They allow you to gather disparate elements together inside a single shape. 
  973. You can use picture shapes for many reasons, including grouping a page of shapes together for printing, to provide a grouping feature in a graphics application, or for programming simplicity to gather a number of shapes together and apply modifications to the group as a whole.
  974. Figure 1-14 shows three sample picture shapes:
  975. n    The first picture shape combines a number of geometric shapes—rectangles, polygons, and paths—into one picture. 
  976. n    The second picture shape includes a bitmap shape as well—the lawn is a gradient or a ramp, which fades from dark to light. 
  977. n    The third picture shape includes typographic shapes in the picture as well.
  978. Figure 1-14    Sample picture shapes
  979.  
  980. Like bitmap shapes, picture shapes make extensive use of their geometry property. A picture shape uses its geometry property to store a list of references to the shapes to be included the picture. Although each of these shapes has its own style, ink, and transform object, picture shapes allow you to provide an overriding style, ink, and transform object for each of these shapes. QuickDraw GX uses this overriding information only when drawing the picture. Even after you insert a shape into a picture, you can still draw the original shape using its original style, ink, and transform object.
  981. Figure 1-15 shows a sample picture shape object and picture geometry.
  982. Figure 1-15    A picture shape
  983.  
  984. The picture shape shown in Figure 1-15 contains references to three other shapes—a polygon shape, a picture shape, and a path shape. It does not contain any overriding styles, inks, or transforms for these shapes.
  985. Figure 1-16 shows a hierarchical view of this picture shape and shows how the picture appears when drawn. This condensed view of a picture shape’s geometry is used in the chapter “Picture Shapes,” in this book, particularly when the picture does not contain overriding styles inks and transforms.
  986. Figure 1-16    A picture hierarchy
  987.  
  988. Notice that the order the shapes appear in the geometry is the order that QuickDraw GX draws them, from back to front.
  989. Since picture shapes contain other shapes, they doen’t make much use of their shape fill property, although you can specify a no-fill shape fill if you don’t want the picture to appear when drawn. 
  990. Picture shapes also don’t make much use of their associated style object, since each shape in the picture has its own style object, and, potentially, an overriding style object.
  991. Pictures shapes also don’t make much use of their ink objects for the same reasons.
  992. Picture shapes do make full use of their transform objects, however. For example, you can scale, skew, rotate, and clip picture shapes as a whole, as well as separately for each individual shape in the picture.
  993. QuickDraw GX also provides powerful tools for hit-testing picture shapes.
  994. For more information about picture shapes, see the chapter “Picture Shapes” in this book.
  995. Listing 2-0
  996. Table 2-0
  997. Geometric Shapes
  998. Contents
  999. About Geometric Shapes2-5
  1000. The Geometric Properties of Shape Objects2-7
  1001. Shape Type2-7
  1002. Shape Geometry2-8
  1003. Shape Fill2-10
  1004. The Geometric Shape Types2-14
  1005. Empty Shapes and Full Shapes2-15
  1006. Point Shapes2-15
  1007. Line Shapes2-16
  1008. Curve Shapes2-17
  1009. Rectangle Shapes2-19
  1010. Polygon Shapes2-20
  1011. Path Shapes2-23
  1012. Using Geometric Shapes2-25
  1013. Creating and Drawing Empty Shapes and Full Shapes2-26
  1014. Creating and Drawing Points2-27
  1015. Creating and Drawing Lines2-32
  1016. Creating and Drawing Rectangles2-36
  1017. Creating and Drawing Curves2-39
  1018. Creating and Drawing Polygons2-40
  1019. Creating Polygons With a Single Contour2-41
  1020. Creating Polygons With Mulitple Contours2-44
  1021. Creating Polygons With Crossed Contours2-45
  1022. Creating and Drawing Paths2-49
  1023. Creating Paths With a Single Contour2-50
  1024. Creating Paths Using Only Off-Curve Points2-52
  1025. Creating Paths With Multiple Contours2-53
  1026. Converting Shapes to Points, Lines, and Rectangles2-57
  1027. Converting Shapes to Curve Shapes2-61
  1028. Converting Shapes to Polygons and Paths2-65
  1029. Replacing Geometric Points2-68
  1030. Editing Polygon Parts2-71
  1031. Editing Paths Parts2-79
  1032. Editing Shape Parts2-81
  1033. Applying Functions Described Elsewhere to Geometric Shapes2-86
  1034. Shape-Related Functions Applicable to Geometric Shapes2-86
  1035. Geometric Operations Applicable to Geometric Shapes2-88
  1036. Style-Related Functions Applicable to Geometric Shapes2-89
  1037. Ink-Related Functions Applicable to Geometric Shapes2-89
  1038. Transform-Related Functions Applicable to Geometric Shapes2-89
  1039. Geometric Shapes Reference2-89
  1040. Data Types2-90
  1041. Point Structure2-90
  1042. Line Structure2-91
  1043. Curves2-91
  1044. Rectangle Structure2-91
  1045. Polygon Structures2-92
  1046. Path Structures2-93
  1047. Functions2-94
  1048. Creating Geometric Shapes2-94
  1049. GXNewPoint 2-95
  1050. GXNewLine 2-96
  1051. GXNewCurve 2-97
  1052. GXNewRectangle 2-98
  1053. GXNewPolygons 2-99
  1054. GXNewPaths 2-101
  1055. Getting and Setting Shape Geometries2-102
  1056. GXGetPoint 2-102
  1057. GXSetPoint 2-103
  1058. GXGetLine 2-104
  1059. GXSetLine  2-105
  1060. GXGetCurve 2-106
  1061. GXSetCurve 2-107
  1062. GXGetRectangle 2-108
  1063. GXSetRectangle 2-109
  1064. GXGetPolygons 2-110
  1065. GXSetPolygons 2-111
  1066. GXGetPaths 2-112
  1067. GXSetPaths 2-114
  1068. Editing Shape Geometries2-115
  1069. GXCountShapeContours 2-116
  1070. GXCountShapePoints 2-116
  1071. GXGetShapeIndex 2-117
  1072. GXGetShapePoints 2-119
  1073. GXSetShapePoints 2-121
  1074. GXGetPolygonParts 2-122
  1075. GXSetPolygonParts 2-123
  1076. GXGetPathParts 2-126
  1077. GXSetPathParts 2-127
  1078. GXGetShapeParts 2-129
  1079. GXSetShapeParts 2-131
  1080. Drawing Geometric Shapes2-134
  1081. GXDrawPoint 2-134
  1082. GXDrawLine 2-135
  1083. GXDrawCurve 2-135
  1084. GXDrawRectangle 2-136
  1085. GXDrawPolygons 2-137
  1086. GXDrawPaths 2-138
  1087. Summary of Geometric Shapes2-139
  1088. Constants and Data Types2-139
  1089. Functions2-140
  1090. Geometric Shapes
  1091. QuickDraw GX provides four basic types of shapes:
  1092. n    geometric shapes
  1093. n    bitmap shapes
  1094. n    picture shapes
  1095. n    typographic shapes
  1096. The first three types—geometric, bitmap, and picture shapes—are described in this book. The fourth type—typographic shapes—are described in Inside Macintosh: QuickDraw GX Typography.
  1097. This chapter describes the geometric shapes. In particular, it shows you how you can define geometries; create geometric shapes; manipulate their shape type, shape fill, and geometry properties; and draw the shapes. Before you read this chapter, you should be familiar with some of the information in in Inside Macintosh: QuickDraw GX Objects. In particular, you should read the chapters “Introduction to QuickDraw GX Objects” and “Shape Objects” in that book.
  1098. The next chapter, “Geometric Styles,” discusses the stylistic variations you can apply to geometric shapes.
  1099. Chapter 4, “Geometric Operations,” describes the functions QuickDraw GX provides for performing operations on the geometries of geometric shapes—operations such as intersection, union, and so on.
  1100. For information about applying colors and transfer modes to geometric shapes, you should read the chapter “Ink Objects” in Inside Macintosh: QuickDraw GX Objects.
  1101. For information about applying mapping transformations to geometric shapes, clipping geometric shapes, and hit-testing geometric shapes, you should read the chapter “Transform Objects” in Inside Macintosh: QuickDraw GX Objects.
  1102.  
  1103. About Geometric Shapes
  1104.  
  1105. QuickDraw GX represents shapes in memory using a shape object and an associated style, ink, and transform object. QuickDraw GX uses these same objects to represent all types of shapes—geometric, bitmap, picture, and typographic.
  1106. A shape object has nine properties, which are like fields of a data structure with one important exception: you cannot directly examine or change the information stored in a property. Instead, you must use QuickDraw GX functions to examine or alter the value of a property.
  1107. Figure 2-1 shows a graphic representation of a shape object and its nine properties.
  1108. Figure 2-1    A shape object
  1109.  
  1110. The first three properties of a shape object—the shape type, shape geometry, and shape fill—are called the geometric shape properties. These properties are examined in detail in “The Geometric Properties of Shape Objects” beginning on page 2-7. In particular, that section describes how these three properties are used by geometric shapes.
  1111. The second three properties of a shape object—the style, ink, and transform properties—are references to the style, ink, and transform objects associated with the shape. Each of these objects contains information that modifies the way QuickDraw GX draws the shape. You can find more information about these objects in Inside Macintosh: QuickDraw GX Objects. In addition, you can find specific information about how style objects affect geometric shapes in Chapter 3, “Geometric Styles,” in this book.
  1112. The final three properties of a shape object—the shape attributes, the owner count, and the tag list—are the object-related shape properties. You can find information about these properties, and how they affect all types of shapes, in the chapter “Shape Objects” of Inside Macintosh: QuickDraw GX Objects.
  1113. QuickDraw GX provides six basic types of geometric shapes:
  1114. n    points
  1115. n    lines
  1116. n    curves
  1117. n    rectangles
  1118. n    polygons
  1119. n    paths
  1120. and two special types:
  1121. n    empty shapes
  1122. n    full shapes
  1123. Each of these shape types is examined in detail in “The Geometric Shape Types” beginning on page 2-14. In particular, that section analyzes how each type of geometric shape uses its shape geometry and shape fill, and also discusses the default geometric shapes.
  1124. The Geometric Properties of Shape Objects
  1125.  
  1126. Every shape object has three geometric properties: the shape type, the shape geometry, and the shape fill. For geometric shapes, these properties define:
  1127. n    the type of shape—for example, whether the shape is a point, line, curve, rectangle, and so on
  1128. n    the coordinates of the shape—for example, the position where a line starts and ends, or the positions of the corners of a rectangle, and so on
  1129. n    how the shape is filled—for example, whether the shape is framed (drawn as an outline) or filled (drawn as a solid area)
  1130. The next three sections examine these properties in more detail.
  1131. Shape Type
  1132.  
  1133. The shape type property of a shape object specifies what type of the shape the shape object represents. There are thirteen different QuickDraw GX shape types: one for bitmap shapes, one for picture shapes, three for typographic shapes, and eight for geometric shapes. The eight geometric shape types are:
  1134. n    point
  1135. n    line
  1136. n    curve
  1137. n    rectangle
  1138. n    polygon
  1139. n    path
  1140. n    empty
  1141. n    full
  1142. The value of the shape type property affects the way QuickDraw GX interprets the other properties of the shape. In particular, different types of shapes store substantially different information in their geometry properties. For example, the geometry of a point shape contains only an x-coordinate and a y-coordinate. The geometry of a line contains an x-coordinate and a y-coordinate to define the beginning of the line and an x-coordinate and a y-coordinate to define the end of the line. The geometry of a polygon shape can contain many pairs of x-coordinates and y-coordinates.
  1143. Figure 2-2 shows a shape object and lists six possible values for its shape type property. This figure also shows a sample geometry for each of the shape types listed. Each geometry is made up of geometric points (x-coordinate/y-coordinate pairs) and edges connecting the geometric points. The next section, “Shape Geometry,” introduces these concepts in more detail.
  1144. Figure 2-2    The geometric shape types and examples of geometric shape geometries
  1145.  
  1146. There are two types of geometric shapes not shown in this figure: the empty shape and the full shape. An empty shape is a shape that has no geometry and covers no area. A full shape is the inverse of an empty shape—it covers all area. You can find more information about these shape types in “Empty Shapes and Full Shapes” beginning on page 2-15.
  1147. Shape Geometry
  1148.  
  1149. Each type of geometric shape uses the geometry property of its shape object in a slightly different manner. For example, empty shapes and full shapes store no information in their geometry, because they require no further geometric information—their shape type says it all.
  1150. However, for other types of geometric shapes, the shape type does not contain all the geometric information necessary to define the shape. The geometries of these shapes contain x-coordinate/y-coordinate pairs called geometric points—points that specify the location, dimension, and form of the geometric shapes:
  1151. n    Point geometries contain one geometric point—an x-coordinate and a y-coordinate—to specify the position of the point shape.
  1152. n    Line geometries contain two geometric points—one point to specify where the line starts and one to specify where the line ends.
  1153. n    Rectangle geometries also contain two geometric points—specifying the positions of opposing corners of the rectangle.
  1154. n    Curve shapes store three geometric points in their geometry—one to specify where the curve starts, another to specify where the curve ends, and another, called the off-curve control point, to specify the tangents used to define the curve.
  1155. Polygon and path geometries are more involved. A polygon shape can contain multiple contours. A polygon contour is a series of geometric points connected by straight lines—for example, a V-shape, a triangle, or a hexagon. 
  1156. Figure 2-2 shows a polygon shape with a single polygon contour made up of three geometric points. This figure shows three views of the polygon geometry: as a list of x-coordinate/y-coordinate pairs, as three geometric points plotted on a geometric grid, and as three points connected by three straight lines. This third way of viewing geometries is used frequently throughout this book, as it shows not only the geometric points, but also the implied edges that connect them.
  1157. Figure 2-3    A polygon shape with a single contour containing three geometric points
  1158.  
  1159. Each geometric point in a geometry has a geometric index—if you consider the geometry as a list of geometric points starting from the first geometric point of the first contour to the last geometric point of the last contour, the geometric index of a particular geometric point is its position in this list. For example, in the shape in Figure 2-2, the first point (0.0, 100.0) has a geometric index of 1, the second point (50.0, 0.0) has a geometric index of 2, and the third point (100.0, 100.0) has a geometric index of 3.
  1160. Notice that each of the three edges of the polygon contour in Figure 2-2 has a direction. The first edge is pointing up and to the right; the second edge is pointing down and to the right; the third edge is pointing to the left. QuickDraw GX considers the direction that an edge is pointing in a number of circumstances:
  1161. n    When filling a shape. QuickDraw GX allows you to choose how a shape should be fileed. The next section, “Shape Fill” beginning on page 2-10, discusses how the direction of an edge can affect how QuickDraw GX fills a shape.
  1162. n    When determining the contour direction of a contour. In the example in Figure 2-2, the polygon contour has a clockwise contour direction. If the geometric points were reversed, the polygon contour would have a counterclockwise contour direction. 
  1163. n    When determining the inside or outside of a contour. QuickDraw GX normally defines the right side of an edge to be the inside and the left side to be the outside. Since the example in Figure 2-2 has a clockwise contour direction, the inside of the contour corresponds to what you would expect the inside to be. If the contour had counterclockwise direction, the inside of the contour would correspond to what you might expect the outside to be.
  1164. QuickDraw GX uses contour direction and the inside and outside of a shape when applying certain stylistic variations, as described in Chapter 3, “Geometric Styles,” and when performing certain geometric operations, as described in Chapter 4, “Geometric Operations,” of this book.
  1165. A path geometry is similar to a polygon geometry, except the contours of a path geometry can contain edges that are curves as well as edges that are straight lines. For more details about the geometries of the various geometric shapes, see “The Geometric Shape Types” beginning on page 2-14.
  1166. Shape Fill
  1167.  
  1168. The shape fill property specifies how QuickDraw GX interprets the geometric points of a geometric shape’s geometry during drawing and other operations. There are two basic types of shape fills:
  1169. n    Framed fills. These shape fills indicate that QuickDraw GX should interpret the shape as an outline—as a series of edges.
  1170. n    Solid fills. These shape fills indicate that QuickDraw GX should interpret the shape as a solid area—the edges of the shape represent the boundaries of the area.
  1171. Figure 2-2 shows an example of a polygon contour similar to the one in Figure 2-2, and how QuickDraw GX might draw it with a framed fill and with a solid fill.
  1172. Figure 2-4    Framing shapes versus filling shapes
  1173.  
  1174. QuickDraw GX actually provides seven types of shape fills:
  1175. n    no-fill shape fill
  1176. n    open-frame shape fill (also called frame fill)
  1177. n    closed-frame shape fill (also called hollow fill)
  1178. n    even-odd shape fill (also called solid fill)
  1179. n    winding shape fill
  1180. n    inverse even-odd shape fill (also called inverse fill and inverse solid fill)
  1181. n    inverse winding shape fill
  1182. Figure 2-5 shows these shape fills and the effect they have on three sample geometries.
  1183. Figure 2-5    The various shape fills and some examples of their effects 
  1184.  
  1185. The no-fill shape fill specifies that QuickDraw GX should not draw the shape. You can use this shape fill to hide a shape. You can specify the no-fill shape fill for any shape type.
  1186. The open-frame shape fill specifies that QuickDraw GX should draw a shape as a connected set of edges. The closed-frame shape fill indicates that QuickDraw GX should also connect the last geometric point of a contour to the first geometric point of that contour. 
  1187. The even-odd shape fill and the winding shape fill indicate that QuickDraw GX should interpret the shape as a solid area—the edges of the shape represent the boundaries of the area. These two shape fills differ in the algorithm they use to determine what area to include in the shape.
  1188. The even-odd shape fill indicates that QuickDraw GX should use the even-odd rule to determine what area lies inside a shape. As QuickDraw GX scans a shape hoizontally, it fills the area between every other pair of edges, as shown in Figure 2-6.
  1189. The winding shape fill indicates that QuickDraw GX should use the winding-number rule to determine what area lies inside a shape. As QuickDraw GX scans a shape horizontally, it increments a counter the first time it crosses an edge of the shape. It also notices whether the contour was directed up or down at that edge. As QuickDraw GX continues to scan the shape horizontally, everytime it crosses another edge pointed in the same direction (up or down), it increments the counter, and when it crosses an edge pointing in the opposite direction (down or up), it decrements the counter. Wherever along the hgorizontal scan line the counter is not zero, QuickDraw GX fills the area, as is shown in Figure 2-6.
  1190. Figure 2-6    The even-odd rule and winding-number rule algorithms
  1191.  
  1192. The inverse even-odd shape fill inverts the area filled by the even-odd shape fill, and the inverse winding shape fill inverts the area filled by the winding shape fill.
  1193. Not all shape fills are appropriate for all types of geometric shapes. For example, a rectangle shape can have a closed-frame shape fill but not an open-frame shape fill. A line shape can only have an open-frame shape fill.
  1194. The open-frame shape fill is the default shape fill for points, lines, and curves. In fact, these shape types may only have the open-frame shape fill or the no-fill shape fill. Polygon shapes may have the open-frame shape fill; rectangles may not. A path shape may have the open-frame shape fill only if its contours start and end with on-curve geometric points—for more information, see “Path Shapes” on page 2-23.
  1195. All rectangles, polygons, and paths may have the closed-frame shape fill.
  1196. The shape fill does more than affect the way a shape is drawn; it affects the fundamental behavior of a shape. Two shapes with the same geometry that have different shape fills can exhibit vastly different geometric behaviors. For example, the shape fill can affect:
  1197. n    stylistic variations, which are described in Chapter 3, “Geometric Styles,” in this book.
  1198. n    shape measurements and other geometric operations, which are discussed in Chapter 4, “Geometric Operations,” in this book. As an example, a polygon with the closed-frame shape fill might simplify to a rectangle. However, the same polygon with the open-frame fill might not simplify at all.
  1199. n    hit-testing, which is described in the chapter “Transform Objects” in Inside Macintosh: QuickDraw GX Objects.
  1200. For examples of shape fills, see
  1201. n    “Polygon Shapes” on page 2-20
  1202. n    “Path Shapes” on page 2-23
  1203. n    “Creating and Drawing Polygons” on page 2-40
  1204. n    “Creating and Drawing Paths” on page 2-49
  1205. The Geometric Shape Types
  1206.  
  1207. QuickDraw GX provides eight types of geometric shapes:
  1208. n    empty shapes
  1209. n    full shapes
  1210. n    point shapes
  1211. n    line shapes
  1212. n    curve shapes
  1213. n    rectangle shapes
  1214. n    polygon shapes
  1215. n    path shapes
  1216. The following sections examine each of these shape types in detail. In particular, these sections discuss how the different types of shapes use their geometry and shape fill properties, and what the default values are for properties of each type of shape.
  1217. Empty Shapes and Full Shapes
  1218.  
  1219. Empty shapes and full shapes are the only geometric shapes with no information stored in the geometry property. 
  1220. An empty shape is a shape with no geometry. When you draw an empty shape, nothing appears. You can use an empty shape when creating other types of shapes. For example, you can create an empty shape and then build it into a polygon shape, adding one contour at a time.
  1221. A full shape is a shape that covers the largest area possible. When you draw a full shape, QuickDraw GX fills in the entire drawable area of the full shape’s view port (paying attention to the clipping information stored in the full shape’s transform). You can use a full shape when erasing an area.
  1222. You commonly use these shapes when performing geometric operations. Therefore, they are described in more detail in Chapter 4, “Geometric Operations.”
  1223. Point Shapes
  1224.  
  1225. The point shape is the simplest of the geometric shapes. Its geometry consists of a single control point—a single (x, y) coordinate pair.
  1226. Point shapes must always have the open-frame shape fill or the no fill shape fill.
  1227. A point shape’s style determines how QuickDraw GX draws the point. If a point’s style has a pen width of 0, which is the default pen width, QuickDraw GX draws the point as a single pixel on the output device. If the style has a pen width greater than 0, QuickDraw GX draws the point only if the style also has a start cap. The next chapter, “Geometric Styles,” discusses these aspects of the style object in more detail.
  1228. When you create a new point shape, QuickDraw GX makes a copy of the default point shape. The default point shape has these properties:
  1229. n    owner count: 1
  1230. n    tags: none
  1231. n    shape attributes: gxNoAttributes
  1232. n    shape type: gxPointType 
  1233. n    shape fill: gxOpenFrameFill
  1234. n    geometry: (0, 0)
  1235. You may change the properties of the default point shape, which effectively changes the behavior of the functions that create point shapes. However, when creating a new point shape, QuickDraw GX always initializes the owner count to 1 and the geometry to (0, 0), despite whatever values you may have specified for the default point shape.
  1236. For examples of creating and drawing point shapes, see “Creating and Drawing Points” beginning on page 2-27.
  1237. Line Shapes
  1238.  
  1239. The geometry of a line shape consists of two geometric points: a first point and a last point. Because the points are ordered, a line has contour direction. 
  1240. Line shapes must always have the open-frame shape fill or the no fill shape fill.
  1241. Figure 2-7 shows two line shapes. The geometries of these two lines have the same geometric points, but in the opposite order. Therefore, the two lines have opposite directions.
  1242. Figure 2-7    Two lines
  1243.  
  1244. If a line shape uses the default style information, the direction of the line does not affect how QuickDraw GX draws the line. However, when you add stylistic variations (such as pen width, pen placement, and dashes) to a line shape, the contour direction of the line can affect how QuickDraw GX draws the line. See the next chapter, “Geometric Styles,” for information about how you can add stylistic variations to a line.
  1245. When you create a new line shape, QuickDraw GX makes a copy of the default line shape. The default line shape has these properties:
  1246. n    owner count: 1
  1247. n    tags: none
  1248. n    shape attributes: gxNoAttributes
  1249. n    shape type: gxLineType 
  1250. n    shape fill: gxOpenFrameFill
  1251. n    geometry: (0, 0),  (0, 0)
  1252. You may change the properties of the default line shape, which effectively changes the behavior of the functions that create line shapes. However, when creating a new line shape, QuickDraw GX always initializes the owner count to 1 and the geometry to (0, 0), (0, 0) despite whatever values you may have specified for the default line shape.
  1253. For examples of creating and drawing line shapes without stylistic variations, see “Creating and Drawing Lines” beginning on page 2-32.
  1254. For examples of creating and drawing lines with stylistic variations, see the next chapter, “Geometric Styles.”
  1255. Curve Shapes
  1256.  
  1257. The geometry of a curve shape consists of three geometric points: a first point, a last point, and an off-curve control point that determines the tangents of the curve. The curve described by these three points is a quadratic Bézier curve—the same type of curve used to describe TrueType fonts.
  1258. Because a curve’s geometric points are ordered, a curve has direction. As with line shapes, direction affects the drawing of a curve only after you apply stylistic variations, which are discussed in the next chapter, “Geometric Styles.”
  1259. Curve shapes must always have the open-frame shape fill or no fill shape fill.
  1260. Figure 2-9 shows an example of a curve shape. In this example, the first point is (50.0, 50.0), the last point is (200.0, 50.0) and the off-curve control point is (100.0, 150.0).
  1261. Figure 2-8    A quadratic Bézier curve
  1262.  
  1263. Quadratic Bézier curves have the following characteristics:
  1264. n    A line connecting the first point and the off-curve control point describes the tangent of the curve at the first point.
  1265. n    A line connecting the off-curve control point and the last point describes the tangent of the curve at the last point.
  1266. n    The curve is always contained by the triangle formed by the three geometric points.
  1267. n    The midpoint of the curve is halfway between the off-curve control point and the point midway between the first point and last point, as shown in Figure 2-9.
  1268. Figure 2-9    Finding the midpoint of a curve
  1269.  
  1270. You can divide a quadratic Bézier curve into two smaller quadratic Bézier curves: 
  1271. n    One smaller curve extends from the first point to the midpoint of the original curve. The new off-curve control point is the point midway between the first point and the original off-curve control point.
  1272. n    The other smaller curve extends from the midpoint to the last point of the original curve. The new off-curve control point is the point midway between the original off-curve control point and the last point.
  1273. Figure 2-9 shows a curve divided into two smaller curves.
  1274. Figure 2-10    Dividing a curve into two smaller curves
  1275.  
  1276. When you create a new curve shape, QuickDraw GX makes a copy of the default curve shape. The default curve shape has these properties:
  1277. n    owner count: 1
  1278. n    tags: none
  1279. n    shape attributes: gxNoAttributes
  1280. n    shape type: gxCurveType 
  1281. n    shape fill: gxOpenFrameFill
  1282. n    geometry: (0.0, 0.0),  (0.0, 0.0),  (0.0, 0.0)
  1283. You may change the properties of the default curve shape, which effectively changes the behavior of the functions that create curve shapes. However, when creating a new curve shape, QuickDraw GX always initializes the owner count to 1 and the geometry to (0.0, 0.0), (0.0, 0.0), (0.0, 0.0) despite whatever values you may have specified for the default curve shape.
  1284. For examples of creating and drawing curve shapes without stylistic variations, see “Creating and Drawing Curves” beginning on page 2-39.
  1285. For examples of creating and drawing curves with stylistic variations, see the next chapter, “Geometric Styles.”
  1286. Rectangle Shapes
  1287.  
  1288. The geometry of a rectangle shape consists of two geometric points. Typically, these geometric points represent the upper-left and lower-right corners of the rectangle; however, you can specify any corner as the first geometric point and the diagonally opposite corner as the second geometric point.
  1289. Rectangle shapes may have any shape fill except the open-frame shape fill.
  1290. Figure 2-7 shows a rectangle geometry and how that rectangle is drawn with a closed-frame shape fill and how it is drawn with an even-odd shape fill.
  1291. Figure 2-11    A rectangle geometry shown framed and filled
  1292.  
  1293. Note
  1294. Note
  1295. Although you may specify a rectangle’s geometric points in any order, QuickDraw GX functions that return rectangles always return rectangles with the upper-left corner as the first geometric point and the lower-left corner as the second geometric point.u
  1296. When you create a new rectangle shape, QuickDraw GX makes a copy of the default rectangle shape. The default rectangle shape has these properties:
  1297. n    owner count: 1
  1298. n    tags: none
  1299. n    shape attributes: gxNoAttributes
  1300. n    shape type: gxRectangleType 
  1301. n    shape fill: gxSolidFill
  1302. n    geometry: (0.0, 0.0),  (0.0, 0.0)
  1303. You may change the properties of the default rectangle shape, which effectively changes the behavior of the functions that create rectangle shapes. However, when creating a new rectangle shape, QuickDraw GX always initializes the owner count to 1 and the geometry to (0.0, 0.0), (0.0, 0.0) despite whatever values you may have specified for the default rectangle shape.
  1304. For examples of creating and drawing rectangle shapes without stylistic variations, see “Creating and Drawing Rectangles” beginning on page 2-36.
  1305. For examples of creating and drawing rectangles with stylistic variations, see the next chapter, “Geometric Styles.”
  1306. Polygon Shapes
  1307.  
  1308. A polygon contour is a series of points connected by straight lines. The geometry of a single polygon contour can have up to 32,767 geometric points.
  1309. A polygon shape may include 0, 1, or more polygon contours. A polygon shape may have up to 32,767 polygon contours.
  1310. Polygon shapes may have any shape fill.
  1311. Figure 2-7 shows a polygon shape that contains two separate contours. The shape is shown four times:
  1312. n    as apolygon shape geometry 
  1313. n    as drawn with the open-frame shape fill
  1314. n    as drawn with the closed-frame shape fill 
  1315. n    as drawn with even-odd shape fill
  1316. Figure 2-12    A polygon shape with two polygon contours
  1317.  
  1318. The first contour in Figure 2-7 has four geometric points and the second contour has three geometric points. Since contours and geometric points are ordered, each geometric point can be numbered from the first geometric point of the first contour to the last geometric point of the last contour. This number is called a geometric point’s geometric index. The geometric points in Figure 2-7 have geometric indexes ranging from 1 to 7. The index of a geometric point within its contour is called its contour index. The geometric points in the first contour in Figure 2-7 have contour indexes ranging from 1 to 4, and the geometric points in the second contour in Figure 2-7 have contour indexes ranging from 1 to 3. You use geometric indexes and contour indexes of geometric points when editing polygon geometries. For examples, see “Editing Polygon Parts” beginning on page 2-71.
  1319. In Figure 2-7, notice that QuickDraw GX does not connect the first point and the last point of a polygon contour with the open-frame shape fill.
  1320. If the contours of a polygon shape cross over one another, or if a polygon shape contains contours that lie within other contours, the even-odd shape fill and the winding shape fill may fill the polygon shape differently, as shown in Figure 2-13.
  1321. Figure 2-13    A polygon drawn with the even-odd and winding shape fills
  1322.  
  1323. The inverse even-odd shape fill indicates the inverse of the even-odd shape fill, as shown in Figure 2-14.
  1324. Figure 2-14    A polygon filled with the inverseFill shape fill
  1325.  
  1326. Similarly, the inverse winding shape fill indicates the inverse of the winding shape fill.
  1327. When you create a new polygon shape, QuickDraw GX makes a copy of the default polygon shape. The default polygon shape has these properties:
  1328. n    owner count: 1
  1329. n    tags: none
  1330. n    shape attributes: gxNoAttributes
  1331. n    shape type: gxPolygonType 
  1332. n    shape fill: gxSolidFill
  1333. n    geometry: 0 contours, 0 points
  1334. You may change the properties of the default polygon shape, which effectively changes the behavior of the functions that create polygon shapes. However, when creating a new polygons shape, QuickDraw GX always initializes the owner count to 1 and the geometry to 0 contours with 0 points, despite whatever values you may have specified for the default polygon shape.
  1335. For examples of creating and drawing polygon shapes without stylistic variations, see “Creating and Drawing Polygons” beginning on page 2-40.
  1336. For examples of creating and drawing polygons with stylistic variations, see the next chapter, “Geometric Styles.”
  1337. Path Shapes
  1338.  
  1339. A path contour, like a polygon contour, is defined by a series of geometric points. However, a path contour can contain off-curve control points as well as on-curve points; therefore, a path contour can contain curves as well as straight lines. 
  1340. The geometry of a single path contour can have up to 32,767 geometric points. 
  1341. A path shape may include 0, 1, or more path contours. A path shape may have up to 32,767 path contours.
  1342. Every path contains an array of control bits that specify which geometric points are on curve and which geometric points are off-curve geometric points. QuickDraw GX connects two consecutive on-curve points with a straight line. If two on-curve points have an off-curve point between them, QuickDraw GX connects the two on-curve points with a quadratic Bézier curve, using the geometric point between them as the off-curve control point.
  1343. QuickDraw GX allows a path to have two or more consecutive off-curve control points. In this case, each pair of consecutive off-curve points implies an on-curve point midway between them.
  1344. Figure 2-15    A path with two consecutive off-curve points
  1345.  
  1346. Path shapes may have any shape fill—including open-frame shape fill. However, a path may not have the open-frame shape fill if the first point or the last point of any path contour is an off-curve point.
  1347. If the contours of a path shape cross over one another, or if a pats shape contains contours that lie within other contours, the even-odd shape fill may fill the path shape differently than the winding shape fill, as shown in Figure 2-16.
  1348. Figure 2-16    A path shape filled with the evenOddFill and windingFill shape fills
  1349.  
  1350. Contour direction affects how QuickDraw GX fills a polygon when the polygon has the winding shape fill. In the example in Figure 2-16, if the inner contour has the opposite contour direction from them outer contour, the winding shape fill works in the same manner as the even-odd shape fill. For more information, see the next section, “Shape Fill.”. For examples, see “Creating and Drawing Paths” beginning on page 2-49.
  1351. When you create a new path shape, QuickDraw GX makes a copy of the default paths shape. The default paths shape has these properties:
  1352. n    owner count: 1
  1353. n    tags: none
  1354. n    shape attributes: gxNoAttributes
  1355. n    shape type: gxPathType 
  1356. n    shape fill: gxSolidFill
  1357. n    geometry: 0 contours, 0 points
  1358. You may change the properties of the default path shape, which effectively changes the behavior of the functions that create path shapes. However, when creating a new path shape, QuickDraw GX always initializes the owner count to 1 and the geometry to 0 contours and 0 geometric points, despite whatever values you may have specified for the default paths shape.
  1359. For examples of creating and drawing paths shapes without stylistic variations, see “Creating and Drawing Paths” beginning on page 2-49.
  1360. For examples of creating and drawing polygons with stylistic variations, see the next chapter, “Geometric Styles.”
  1361.  
  1362. Using Geometric Shapes
  1363.  
  1364. This section shows you how to create, edit, and draw geometric shapes. In particular, this section shows you how to 
  1365. n    create and draw empty and full shapes
  1366. n    create point, line, curve, rectangle, polygon, and path shapes
  1367. n    draw points, lines, curves, rectangles, polygons, and paths
  1368. n    create framed and filled shapes
  1369. n    convert a shape from one shape type to another
  1370. n    replace the geometry of a shape
  1371. n    replace geometric points within a shape’s geometry
  1372. n    insert geometric points into and remove geometric points from a shape’s geometry
  1373. All of the sample functions in this section create geometric shapes with default style, ink, and transform information. All shapes are black, framed shapes have one-pixel-wide contours, and the shapes are not rotated, skewed, and so on. For examples of the many stylistic variations you can apply to geometric shapes, see Chapter 3 of this book, “Geometric Styles.” For information about inks and transforms, see Inside Macintosh: QuickDraw GX Objects.
  1374. Many of the sample functions in this section create geometric shapes and, to do so, they specify geometric points for the shapes’ geometries. Since a geometric point contains two fixed-point values (of type fixed), the sample functions in this section must convert integer constants to fixed-point constants when specifying a geometric point. QuickDraw GX provides the GXIntToFixed macro, which performs this conversion by shifting the integer value 16 bits to the left:
  1375. #define GXIntToFixed(a) ((fixed)(a) << 16)
  1376. QuickDraw GX also provides the ff macro as a convenient alias:
  1377. #define ff(a) GXIntToFixed(a)
  1378. A few of the sample functions in this section specify fractional values for geometric point coordinates. To convert a floating-point value (of type float) to a fixed-point value (type fixed), QuickDraw GX provides the GXFloatToFixed macro:
  1379. #define GXFloatToFixed(a) ((fixed)((float)(a) * fix1))
  1380. and the synonomous fl macro:
  1381. #define fl(a) GXFloatToFixed(a)
  1382. IMPORTANT
  1383. The GXIntToFixed macro has substantially faster performance than the GXFloatToFixed macro. Whenever possible, you should choose the GXIntToFixed macro over the GXFloatToFixed macro.s
  1384. Creating and Drawing Empty Shapes and Full Shapes
  1385.  
  1386. To create an empty shape or a full shape, you use the function GXNewShape, which is described in full in the chapter “Shape Objects” of Inside Macintosh: QuickDraw GX Objects.
  1387. To create an empty shape, you could define a shape reference and then call the GXNewShape function:
  1388. gxShape anEmptyShape;
  1389.  
  1390. anEmptyShape = GXNewShape(gxEmptyType);
  1391. Alhtough you can draw this shape with the GXDrawShape function, nothing will appear. However, you can use empty shapes for other purposes. For example, you can create an empty shape and then add geometric points to it using the SetShapeParts function, building other types of shapes as you add points. See “Editing Shape Parts” beginning on page 2-81 for examples of this function.
  1392. To create a full shape, you can use this code:
  1393. gxShape aFullShape;
  1394.  
  1395. aFullShape = GXNewShape(gxFullType);
  1396. You can then draw the full shape to cover the entire area of the shape’s view ports. For example, you could use the full shape to erase an area, or you could set the color of the full shape and draw it to create a colored background before drawing other shapes.
  1397. Creating and Drawing Points 
  1398.  
  1399. QuickDraw GX provides a number of methods to create and draw geometric shapes. In general, to draw a shape you must first define a geometry. You can then draw the shape in one of two ways:
  1400. n    You can draw the geometry directly—without having to create a shape object.
  1401. n    You can create a shape object to encapsulate the geometry and then draw the shape.
  1402. The first sample function in this section, shown in Listing 2-1, uses the first method—it draws a point without creating a point shape.
  1403. To draw the point, this sample function first defines a point geometry, which is represented by a point structure (of type gxPoint):
  1404. struct gxPoint{
  1405.     fixed            x;
  1406.     fixed            y;
  1407. };
  1408. The value in the x field specifies horizontal distance from the origin; greater values indicate distances further to the right. The value in the y field specifies vertical distance from the origin; greater values indicate distances further down. 
  1409. Note
  1410. The coordinates of a shape’s geometry go through a number of transformations before the shape is actually drawn. Where the shape is drawn depends not only on the values of the shape’s geometry, but also on the shape’s associated transform and view port objects. If you use the default transform and view port information, the coordinates in a shape’s geometry represent units of 1/72 inch and the origin is the upper-left corner of the view port. See Inside Macintosh: QuickDraw GX Objects for more information about the coordinate systems of QuickDraw GX.u
  1411. Since each coordinate of a point must be a fixed-point value, the sample function in Listing 2-1 uses the GXIntToFixed macro to convert integer constants to fixed-point constants.
  1412. The sample function then draws the point using the GXDrawPoint function. The GXDrawPoint function takes a pointer to a gxPoint structure as its only parameter and draws the corresponding point. When drawing the point, it uses the style, ink, and transform information associated with the default point shape.
  1413. Listing 2-1    Drawing a point without creating a point shape
  1414.  
  1415. void DrawASinglePoint(void)
  1416. {
  1417.     static gxPoint                 aPointGeometry = {GXIntToFixed(5),
  1418.                                                 GXIntToFixed(5)};
  1419.     
  1420.     GXDrawPoint(&aPointGeometry);
  1421. }
  1422. QuickDraw GX provides the ff macro as an alias for the GXIntToFixed macro. In the example in Listing 2-1, the point coordinates could be specified with this line of code:
  1423. static gxPoint aPointGeometry = {ff(5), ff(5)};
  1424. The rest of the examples in this section use this convenient alternative.
  1425. Figure 2-17 shows the result of the sample function from Listing 2-1.
  1426. Figure 2-17    A point
  1427.  
  1428. Listing 2-1 defines the point at location (5.0, 5.0), which lies at the intersection of two infinitely-thin grid lines, and therefore is infinitely thin itself. However, when QuickDraw GX draws this point shape, it draws it as a single pixel—the pixel lying dwon and to the right of the point itself, as shown in Figure 2-17. QuickDraw GX only draws this single-pixel type of point, called a hairline point, if the pen width property of the style object associated with the point shape has a value of 0, which is the default value for this property. For more information about the pen width property and how it affects the drawing of point shapes, see the chapter “Geometric Styles,” in this book.
  1429. Although you may sometimes want to draw a shape without creating a shape object for it, you will frequently want to create a shape object before drawing a shape. Creating a shape object has many advantages; for example, it allows you to provide custom style, ink, and transform information before drawing the shape.
  1430. QuickDraw GX provides three main methods for creating geometric shapes:
  1431. n    You can call a type-specific function, such as GXNewPoint, which requires you to provide a pointer to the shape’s desired geometric structure.
  1432. n    You can call the GXNewShapeVector function, which requires you to specify the shape type and provide a pointer to the shape’s desired geometric structure.
  1433. n    you can call the GXNewShape function, which requires you to specify the desired shape type, and then call a type-specific function, such as GXSetPoint, to set the geometry.
  1434. The sample functions in Listing 2-2, Listing 2-3, and Listing 2-4 each show how to create a point shape using these three methods.
  1435. Listing 2-2 uses the GXNewPoint function to create a point shape given a pointer to a point geometry.
  1436. Listing 2-2    Creating a point shape with the GXNewPoint function
  1437.  
  1438. void CreatePointShape(void)
  1439. {
  1440.     gxShape                  aPointShape;
  1441.  
  1442.     static gxPoint     aPointGeometry = {ff(5), ff(5)}; 
  1443.     
  1444.         
  1445.     aPointShape = GXNewPoint(&aPointGeometry);
  1446.     
  1447.     GXDrawShape(aPointShape);
  1448. }
  1449. Listing 2-3 uses the GXNewShapeVector function to create a point shape. The GXNewShapeVector function requires two parameters:
  1450. n    the shape type of the shape you want to create 
  1451. n    an array of fixed-point values that represent the shape’s geometry
  1452. In this example, the desired shape type is gxPointType and the geometry is specified as an array of two fixed-point values representing the coordinates of the point’s geometry. When using the GXNewShapeVector function to create shapes more complicated than point shapes, you need to provide more values in this array.
  1453. Listing 2-3    Creating a point shape with the GXNewShapeVector function
  1454.  
  1455. void CreatePointShape(void)
  1456. {
  1457.     gxShape                  aPointShape;
  1458.     static fixed         aPointGeometry[] = {ff(5), ff(5)};
  1459.  
  1460.  
  1461.     aPointShape = GXNewShapeVector(gxPointType, aPointGeometry);
  1462.  
  1463.     GXDrawShape(aPointShape);
  1464. }
  1465. Listing 2-4 creates a point shape using the GXNewShape function. The GXNewShape function requires only that you specify the type of shape to create. You do not have to specify any values for the geometric points of the shape’s geometry—the GXNewShape function uses the values from the default shape of the appropriate type.
  1466. To set the values of the point shape’s geometry once it’s created, the sample function in Listing 2-4 uses the GXSetPoint function. This function takes a reference to the shape and a pointer to the desired geometry as its parameters. 
  1467. Listing 2-4    Creating a point shape with the GXNewShape and GXSetPoint functions
  1468.  
  1469. void CreatePointShape(void)
  1470. {
  1471.     gxShape             aPointShape;
  1472.  
  1473.     static gxPoint     aPointGeometry = {ff(5), ff(5)}; 
  1474.     
  1475.         
  1476.     aPointShape = GXNewShape(gxPointType);
  1477.     GXSetPoint(aPointShape, &aPointGeometry);
  1478.     
  1479.     GXDrawShape(aPointShape);
  1480. }
  1481. The sample functions in Listing 2-2, Listing 2-3, and Listing 2-4 all use the GXDrawShape function to draw the point after the point shape has been created. The resulting point is the same for all three examples; it appears as shown in Figure 2-17.
  1482. You can use the GXSetPoint function to replace a point shape’s geometry any number of times. The sample function in Listing 2-5 creates a point shape, sets its geometry using the GXSetPoint function, draws the point, replaces its geometry using the GXSetPoint function, and draws the point again.
  1483. Listing 2-5    Using the GXSetPoint function to replace a point shape’s geometry
  1484.  
  1485. void ReplacePointShapeGeometry(void)
  1486. {
  1487.     gxShape             aPointShape;
  1488.  
  1489.     static gxPoint     aPointGeometry = {ff(5), ff(5)}; 
  1490.     static gxPoint     anotherPointGeometry = {ff(13), ff(8)}; 
  1491.     
  1492.         
  1493.     aPointShape = GXNewShape(gxPointType);
  1494.     GXSetPoint(aPointShape, &aPointGeometry);
  1495.     GXDrawShape(aPointShape);
  1496.  
  1497.     GXSetPoint(aPointShape, &anotherPointGeometry);
  1498.     GXDrawShape(aPointShape);
  1499. }
  1500. Figure 2-18 depicts the results of this sample function. 
  1501. Figure 2-18    Two different point geometries
  1502.  
  1503. Most of the sample functions discussed in this section create shape objects. If you create a shape object using any of the methods discussed, you are responsible for disposing of the shape when you no longer need it. You can do this using the GXDisposeShape function, which decrements the owner count of the shape and frees the memory occupied by that shape if the shape’s owner count becomes 0. In the examples of this section, you could dispose of the point shape by calling
  1504. GXDisposeShape(aPointShape);
  1505. Since the GXNewPoint, GXNewShapeVector, and GXNewShape functions all return a shape with an owner count of 1, calling the GXDisposeShape function in the three previous examples would decrement the owner count to 0 and therefore purge the point shape from memory. For a complete discussion of creating and disposing of shapes, see Inside Macintosh: QuickDraw GX Objects.
  1506. For more information about point shapes, see “Point Shapes” on page 2-15 and “Point Structure” on page 2-90.
  1507. For information about the functions you can use to create and draw points, see the description of the GXNewPoint function on page 2-95 and the GXDrawPoint function on page 2-134.
  1508. Creating and Drawing Lines
  1509.  
  1510. You can draw lines and create line shapes with QuickDraw GX in much the same way as you draw points and create point shapes. Typically, you first define a line geometry, which is encapsulated in a gxLine structure:
  1511. struct gxLine {
  1512.     struct gxPoint                    first;
  1513.     struct gxPoint                    last;
  1514. };
  1515. Once you’ve defined a line geometry, you can draw the corresponding line without creating a line shape by using the GXDrawLine function, as shown in Listing 2-6.
  1516. Listing 2-6    Drawing a line without creating a line shape
  1517.  
  1518. void DrawASingleLine(void)
  1519. {
  1520.     static gxLine                 aLineGeometry = {{ff(50), ff(50)},
  1521.                                            {ff(150), ff(150)}};     
  1522.     
  1523.     GXDrawLine(&aLineGeometry);
  1524. }
  1525. This sample function defines a line geometry, using the ff macro (which is an alias for the GXIntToFixed macro) to convert integer constants to fixed-point coordinate values. It then uses the GXDrawLine function to draw the line. The GXDrawLine function uses the style, ink, and transform information from the default line shape when drawing the line. The result is shown in Figure 2-19.
  1526. Figure 2-19    A line
  1527.  
  1528. As with the point shape in Figure 2-17, the line shape in Figure 2-19 is infinitely then, but is drawn one-pixel wide—a hairline—because the default value of the pen width property of the style object is 0, which indicates that QuickDraw GX should draw the line at the thinnest perceivable resolution.
  1529. Another method of drawing a line is to encapsulate the line geometry into a line shape and then use the GXDrawShape function to draw the line. This method allows you to specify different style, ink, and transform information for the line.
  1530. The sample function in Listing 2-7 uses this method: it creates a line shape using the GXNewLine function and then draws the line using the GXDrawShape function.
  1531. Listing 2-7    Creating a line shape with the GXNewLine function
  1532.  
  1533. void CreateLineShape(void)
  1534. {
  1535.     gxShape                aLineShape;
  1536.     
  1537.     static gxLine                 aLineGeometry = {ff(50), ff(50),
  1538.                                            ff(150), ff(150)};     
  1539.     
  1540.     
  1541.     aLineShape = GXNewLine(&aLineGeometry);
  1542.     
  1543.     GXDrawShape(aLineShape);
  1544. }
  1545. You can also use the GXNewShape or GXNewShapeVector functions to create a line shape. For example, to create the same line shape using the GXNewShape function, you could replace this line of code in the previous example:
  1546. aLineShape = GXNewLine(&aLineGeometry);
  1547. with these lines of code:    
  1548. aLineShape = GXNewShape(gxLineType);
  1549. GXSetLine(aLineShape, &aLineGeometry);
  1550. In either case, the line shape would be the same, and would appear as shown in Figure 2-19.
  1551. The sample function in Listing 2-8 shows how to use the GXSetLine function to change the geometry of an existing line shape.
  1552. Listing 2-8    Drawing two parallel lines
  1553.  
  1554. void DrawParallelLines(void)
  1555. {
  1556.     gxShape                 aLineShape;
  1557.     
  1558.     static gxLine                 aLineGeometry = {ff(50), ff(50),
  1559.                                              ff(57), ff(100)};     
  1560.  
  1561.     static gxLine         anotherLineGeometry = {ff(60), ff(50),
  1562.                                                 ff(67), ff(100)};     
  1563.     
  1564.     
  1565.     aLineShape = GXNewShape(gxLineType);
  1566.     GXSetLine(aLineShape, &aLineGeometry);
  1567.  
  1568.     GXDrawShape(aLineShape);
  1569.     
  1570.     GXSetLine(aLineShape, &anotherLineGeometry);
  1571.     
  1572.     GXDrawShape(aLineShape);
  1573. }
  1574. This sample function creates and draws a line shape, changes its geometry, and then draws it again. The results are shown in Figure 2-20.
  1575. Figure 2-20    Parallel lines
  1576.  
  1577. As with any geometric shape, you can specify fractional values for a line shape’s geometric points. Although specifying a fractional part does not move the start pixel or the end pixel of line (unless rounding occurs), it can affect how the line is drawn. When QuickDraw GX draws a line with fractional endpoint coordinates, it may choose different pixels to represent the line, even if the endpoints remain on the same pixels. By choosing a different “stair step” pattern to represent the line, QuickDraw GX can give the illusion of very slight changes in line angles. As an example, if in the previous example you replace the second definition:
  1578. static gxLine         anotherLineGeometry = {ff(60), ff(50),
  1579.                                                ff(67), ff(100)};
  1580. with a slightly modified version:
  1581. static gxLine         anotherLineGeometry = {fl(59.6), ff(50),
  1582.                                               fl(67.4), ff(100)}; 
  1583. QuickDraw GX chooses different pixels to represent the second line, giving the appearance of a slightly different angle, as shown in Figure 2-21.
  1584. Figure 2-21    Nearly parallel lines
  1585.  
  1586. For more information about line shapes, see “Line Shapes” on page 2-16 and “Line Structure” on page 2-91.
  1587. For information about the functions you can use to create and draw lines, see the description of the GXNewLine function on page 2-96 and the GXDrawLine function on page 2-135.
  1588. Creating and Drawing Rectangles
  1589.  
  1590. You can create rectangle shapes and draw rectangles with QuickDraw GX the same way you create and draw points and lines. Typically, you first define a rectangle geometry, which is encapsulated in a gxRectangle structure:
  1591. struct gxRectangle {
  1592.     fixed            left;
  1593.     fixed            top;
  1594.     fixed            right;
  1595.     fixed            bottom;
  1596. };
  1597. Note
  1598. QuickDraw GX allows you to specify rectangle coordinates out of order—that is, you can specify any corner of the rectangle using the first two fields of the rectangle structure and the opposing corner using the second two fields of the rectangle structure.u
  1599. Once you’ve defined a rectangle geometry, you can draw the corresponding rectangle without creating a rectangle shape by using the GXDrawRectangle function, which is described on page 2-136, or you can create a rectangle shape and draw it with the GXDrawShape function, as shown in Listing 2-9.
  1600. Listing 2-9    Creating a rectangle shape
  1601.  
  1602. void CreateRectangle(void)
  1603. {
  1604.     gxShape         aRectangleShape;
  1605.     
  1606.     static gxRectangle aRectangleGeometry = {ff(50), ff(50),
  1607.                                                                 ff(150), ff(100)}; 
  1608.                                           
  1609.     
  1610.     aRectangleShape = GXNewRectangle(&aRectangleGeometry);
  1611.     
  1612.     GXDrawShape(aRectangleShape);
  1613. }
  1614. This sample function uses the ff macro (which is an alias for the IntegerToFixed macro) to convert integer constants to the fixed-poinat coordinate values needed to define a rectangle geometry. It then creates a rectangle shape using the GXNewRectangle function (although it could use the GXNewShape function or the GXNewShapeVector function instead) and draws the rectangle using the GXDrawShape function. The result is shown in Figure 2-22.
  1615. Figure 2-22    A rectangle
  1616.  
  1617. Notice that the rectangle is filled rather than framed. The GXNewRectangle function returns a new rectangle shape with the same shape fill property as the default rectangle shape, which is the even-odd shape fill.
  1618. Note
  1619. Although initially QuickDraw GX sets the shape fill property of the default rectangle shape to be gxEvenOddFill, you may change the default shape fill for rectangles by using the GXGetDefaultShape function to obtain a reference to the default rectangle and then using the GXSetShapeFill function to change its shape fill.) You can similarly change the default shape fill for any shape type.u
  1620. To create a framed rectangle, you can use the GXSetShapeFill function to change the shape fill from even-odd to closed-frame, as shown in Listing 2-10.
  1621. Listing 2-10    Creating a framed rectangle
  1622.  
  1623. void CreateFramedRectangle(void)
  1624. {
  1625.     gxShape aRectangleShape;
  1626.     
  1627.     static gxRectangle                         aRectangleGeometry = {ff(150), ff(100),
  1628.                                                                     ff(50), ff(50)}; 
  1629.                                           
  1630.     
  1631.     aRectangleShape = GXNewRectangle(&aRectangleGeometry);
  1632.     GXSetShapeFill(aRectangleShape, gxClosedFrameFill);
  1633.     
  1634.     GXDrawShape(aRectangleShape);
  1635. }
  1636. Figure 2-23 shows the result of Listing 2-10.
  1637. Figure 2-23    A framed rectangle
  1638.  
  1639. In general, a rectangle must have a no-fill, closed-frame, even-odd, winding, inverse even-odd, or inverse winding shape fill. For more information about rectangle shapes, see “Rectangle Shapes” on page 2-19 and “Rectangle Structure” on page 2-91.
  1640. For more information about the shape fill property, see “Shape Fill” on page 2-10.
  1641. For information about the functions you can use to create and draw lines, see the description of the GXNewRectangle function on page 2-98 and the GXDrawRectangle function on page 2-136.
  1642. Creating and Drawing Curves
  1643.  
  1644. You can create and draw curve shapes with QuickDraw GX the same way you create and draw points, lines, and rectangles. Typically, you first define a curve geometry, which is encapsulated in a gxCurve structure:
  1645. struct gxCurve {
  1646.     struct gxPoint             first;
  1647.     struct gxPoint             control;
  1648.     struct     gxPoint             last;
  1649. };
  1650. The first and last fields determine the start point and the end point of the curve. The point specified in the control field lies off the curve and determines the tangents of the curve. (The off-curve control point could actually be on the curve—that is, directly between the first and last points—in which case the curve is a straight line.)
  1651. Once you’ve defined a curve geometry, you can create a curve shape using the GXNewCurve function and draw it using the GXDrawShape function, as shown in Listing 2-11.
  1652. Listing 2-11    Creating a curve shape
  1653.  
  1654. void CreateCurve(void)
  1655. {
  1656.     gxShape         aCurveShape;
  1657.     
  1658.     gxCurve         aCurveGeometry = {ff(50), ff(50),   /* on curve */
  1659.                                       ff(100), ff(150), /* off curve */ 
  1660.                                       ff(200), ff(50)}; /* on curve */ 
  1661.                                           
  1662.     
  1663.     aCurveShape = GXNewCurve(&aCurveGeometry);
  1664.     
  1665.     GXDrawShape(aCurveShape);
  1666. }
  1667. Figure 2-24 shows the curve shape geometry, which includes the first and last points, the off-curve control point, and the tangents implied by these geometric points. This figure also shows the curve as drawn. It is drawn with the open-frame shape fill, as this shape fill is the default for curve shapes, and it is drawn as a hairline (one-pixel wide) as this pen width is the default for style objects.
  1668. Figure 2-24    A curve shape
  1669.  
  1670. You could draw the same curve without creating a curve shape by calling the GXDrawCurve function:
  1671. GXDrawCurve(&aCurveGeometry);
  1672. You could also create the curve shape using the GXNewShape or the GXNewShapeVector functions, described in Inside Macintosh: QuickDraw GX Objects. 
  1673. Curves have a direction that depends on the order of the points in the geometry. For example, you could reverse the direction of the curve in Figure 2-24 by reversing the order of the points in the geometry definition from Listing 2-11:
  1674. gxCurve aCurveGeometry = {ff(200), ff(50),  /* on curve */
  1675.                                   ff(100), ff(150), /* off curve */
  1676.                                   ff(50), ff(50)};  /* on curve */
  1677. Changing the direction of this curve would not change its appearance. However, curve direction can affect the appearance of a curve when you apply certain stylistic variations, such as dashing, to the curve. The next chapter, “Geometric Styles,” discusses these stylistic variations. Also, when a curve is part of a path shape, the direction of the curve can affect the way the path is drawn. See “Creating and Drawing Paths” on page 2-49 for examples of how the direction of a curve can affect drawing.
  1678. For more information about curve shapes, see “Curve Shapes” on page 2-17 and “Curves” on page 2-91.
  1679. For information about the functions you can use to create and draw curves, see the description of the GXNewCurve function on page 2-97 and the GXDrawCurve function on page 2-135.
  1680. Creating and Drawing Polygons
  1681.  
  1682. A polygon contour is a series of points connected by straight lines. QuickDraw GX defines the gxPolygon structure to encapsulate a polygon contour:
  1683. struct gxPolygon {
  1684.     long                   vectors;
  1685.     struct gxPoint vector[gxAnyNumber];
  1686. };
  1687. The vectors field indicates the number of points in the polygon and the vector array contains the points themselves. (The constant gxAnyNumber is used as a placeholder, since a polygon contour can have any number of geometric points—up to 32767.)
  1688. The polygon shape type allows you to group any number of polygon contours within a single QuickDraw GX shape. The gxPolygons structure encapsulates the multiple-polygon geometry:
  1689. struct gxPolygons {
  1690.     long                       contours;
  1691.     struct gxPolygon             contour[gxAnyNumber];
  1692. };
  1693. The contours field indicates the total number of contours (in other words, the total number of separate polygons), and the contour array contains the polygon contour geometries.
  1694. Creating Polygons With a Single Contour
  1695.  
  1696. Since a gxPolygons structure is of variable length and every element in it is of type long, you can define a polygon geometry as an array of long values. For example, the definition
  1697. long        aPolygonGeometry[] = {1, /* number of contours */
  1698.                                      3, /* number of points */
  1699.                                      ff(50), ff(50),   
  1700.                                      ff(100), ff(80), 
  1701.                                      ff(50), ff(110)};
  1702. defines a polygon geometry with one contour (that is, with one polygon). The polygon contains three points; it is a triangle.
  1703. Most QuickDraw GX functions that create or draw polygon shapes expect a pointer to a gxPolygons structure as one of the parameters. Therefore, you must cast an array of long values to the correct type before sending it to one of these functions. As an example, you can cast the aPolygonGeometry array to the correct type with this expression:
  1704. (gxPolygons *) aPolygonGeometry
  1705. The sample function in Listing 2-12 shows how to use this geometry to draw a triangle.
  1706. Listing 2-12    Drawing a triangular polygon
  1707.  
  1708. void DrawTriangle(void)
  1709. {
  1710.     static long                aPolygonGeometry[] = {1, /* number of contours */
  1711.                                                    3, /* number of points */
  1712.                                                    ff(50), ff(50),   
  1713.                                                        ff(100), ff(80), 
  1714.                                                        ff(50), ff(110)};
  1715.                                           
  1716.     
  1717.     GXDrawPolygons((gxPolygons *) aPolygonGeometry, gxEvenOddFill);
  1718. }
  1719. This sample function defines the aPolygonGeometry array, casts it to a gxPolygons pointer, and sends it to the GXDrawPolygons function. Unlike the GXDrawPoint, GXDrawLine, GXDrawCurve, and GXDrawRectangle functions, the GXDrawPolygons function takes a second parameter—the shape fill to use when drawing the polygon shape. In this example, the parameter is set to the gxEvenOddFill value and the resulting polygon is shown in Figure 2-25.
  1720. Figure 2-25    A triangular polygon
  1721.  
  1722. You can specify any type of shape fill for polygon shapes. For example, if you specify tthe inverse even-odd shape fill:
  1723. GXDrawPolygons((gxPolygons *) aPolygonGeometry,
  1724.                     gxInverseEvenOddFill);
  1725. QuickDraw GX draws the graphic shown in Figure 2-26. The black portion of the drawing would be clipped according to the information in the default polygon shape’s transform object. If no clipping information is specified there, the drawing would extend to the full range of the shape’s view port.
  1726. Figure 2-26    A triangular polygon with an inverse shape fill
  1727.  
  1728. For information on clipping and view ports, see Inside Macintosh: QuickDraw GX Objects.
  1729. Although this example draws the polygon without creating a polygon shape, it could instead create a polygon shape with the GXNewPolygons function: 
  1730. aPolygonShape = GXNewPolygons((gxPolygons *) aPolygonGeometry);
  1731. and then draw it using the GXDrawShape function:
  1732. GXDrawShape(aPolygonShape);
  1733. You can also create polygon shapes using the GXNewShape function:
  1734. aPolygonShape = GXNewShape(gxPolygonType);    GXSetPolygons(aPolygonShape, (gxPolygons *) aPolygonGeometry);
  1735. or by using the GXNewShapeVector function:
  1736. aPolygonShape = GXNewShapeVector(gxPolygonType, aPolygonGeometry);
  1737. Notice that in this case you do not have to cast the aPolygonGeometry array to be a pointer to a gxPolygons structure. The GXNewShapeVector function expects an array of long values.
  1738. Although the GXDrawPolygons function (shown in Listing 2-12) allows you to specify a shape fill, the GXDrawShape function does not. If you create a polygon shape and you want it have a different shape fill than the default polygon shape, you must indicate the desired shape fill using the GXSetShapeFill function—for example, 
  1739. GXSetShapeFill(aPolygonShape, gxInverseEvenOddFill);
  1740. For more information about shape fills, see “Shape Fill” on page 2-10.
  1741. Creating Polygons With Mulitple Contours
  1742.  
  1743. The sample function in Listing 2-13 shows how a single polygon shape can contain more than one polygon contour. The polygon shape defined in this example includes the triangle from the previous example as well as a second, entirely separate, triangle.
  1744. Listing 2-13    Creating a polygon with two contours
  1745.  
  1746. void DrawTwoTriangles(void)
  1747. {
  1748.     gxShape                aPolygonsShape;
  1749.     
  1750.     static long                aPolygonsGeometry[] = {2, /* number of contours */
  1751.                                                      3, /* number of points */
  1752.                                                       ff(50), ff(50),   
  1753.                                                          ff(100), ff(80), 
  1754.                                                          ff(50), ff(110),
  1755.                                                      3, /* number of points */
  1756.                                                 ff(200), ff(50),   
  1757.                                                ff(150), ff(80), 
  1758.                                                ff(200), ff(110)};
  1759.                                           
  1760.     
  1761.     aPolygonsShape = GXNewPolygons((gxPolygons *)
  1762.                                               aPolygonsGeometry);
  1763.     
  1764.     GXDrawShape(aPolygonsShape);
  1765. }
  1766. This sample function results in the drawing shown in Figure 2-27.
  1767. Figure 2-27    A filled polygon with two separate contours
  1768.  
  1769. For more information about polygon shapes and multiple contours, see “Polygon Shapes” on page 2-20.
  1770. Creating Polygons With Crossed Contours
  1771.  
  1772. Since a polygon contour is defined as an array of geometric points connected by straight lines, it is possible for the lines that make up a polygon contour to cross over each other. The sample function in Listing 2-14 creates such a polygon.
  1773. Listing 2-14    Creating a polygon with a crossed contour
  1774.  
  1775. void CreateCrossedContour(void)
  1776. {
  1777.     gxShape                aPolygonsShape;
  1778.     
  1779.     static long                aPolygonsGeometry[] = {1, /* number of contours */
  1780.                                                      4, /* number of points */
  1781.                                                      ff(50), ff(50),   
  1782.                                                          ff(150), ff(110), 
  1783.                                                         ff(150), ff(50), 
  1784.                                                         ff(50), ff(110)};
  1785.                                           
  1786.     
  1787.     aPolygonsShape = GXNewPolygons((gxPolygons *) 
  1788.                                              aPolygonsGeometry);
  1789.     GXSetShapeFill(aPolygonsShape, gxClosedFrameFill);
  1790.     
  1791.     GXDrawShape(aPolygonsShape);
  1792. }
  1793. Figure 2-28 shows the geometry of the resulting polygon contour as well as how the contour appears when drawn with the closed-frame shape fill.
  1794. Figure 2-28    A framed polygon with a crossed contour
  1795.  
  1796. You can change the shape fill of this polygon by removing this line of code from the sample function in Listing 2-14:
  1797. GXSetShapeFill(aPolygonsShape, gxClosedFrameFill);
  1798. If you don’t specify a shape fill, the GXNewPolygons function uses the shape fill from the default polygon, which is the even-odd shape fill (unless you change it using the GXGetDefaultShape and GXSetShapeFill functions). The polygon resulting from an even-odd shape fill is shown in Figure 2-29.
  1799. Figure 2-29    A filled polygon with crossed contour
  1800.  
  1801. Notice that QuickDraw GX fills both sections of this polygon. 
  1802. It is possible to create a polygon with a contour that overlaps in such a way that QuickDraw GX does not fill all sections of the polygon. The sample function in Listing 2-15 creates such a polygon.
  1803. Listing 2-15    Creating a polygon with an overlapping contour
  1804.  
  1805. void CreateOverlappingContour(void)
  1806. {
  1807.     gxShape                aPolygonShape;
  1808.     
  1809.     static long                aPolygonGeometry[] = {1, /* number of contours */
  1810.                                                    6, /* number of points */
  1811.                                                    ff(50), ff(50),   
  1812.                                                       ff(100), ff(80), 
  1813.                                                       ff(25), ff(150), 
  1814.                                                      ff(25), ff(10), 
  1815.                                                      ff(100), ff(80), 
  1816.                                                      ff(50), ff(110)};
  1817.     
  1818.     aPolygonShape = GXNewPolygons((gxPolygons *) aPolygonGeometry);
  1819.     GXSetShapeFill(aPolygonShape, gxHollowFill);
  1820.     
  1821.     GXDrawShape(aPolygonShape);
  1822. }
  1823. Figure 2-30 shows the geometry of the resulting polygon contour as well as how the contour appears when drawn with the closed-frame shape fill.
  1824. Figure 2-30    A framed polygon with an overlapping contour and closed-frame shape fill
  1825.  
  1826. If you specified the even-odd shape fill for this polygon, instead of the closed-frame shape fill, the resulting shape would appear as in Figure 2-31. 
  1827. Figure 2-31    A even-odd filled polygon with an overlapping contour and even-odd shape fill
  1828.  
  1829. Notice that QuickDraw GX fills in the polygon but does not fill in the area contained in the inner loop. The algorithm used by QuickDraw GX to fill in shapes with the even-odd shape fill doesn’t fill loops within the shape. (It would, however, fill a loop inside a loop.)
  1830. The winding shape fill works differently. If you specify the winding shape fill for this polygon using the call
  1831. GXSetShapeFill(aPolygonShape, gxWindingFill);
  1832. QuickDraw GX draws the polygon as shown in Figure 2-32.
  1833. Figure 2-32    A contour with an overlapping contour and winding shape fill
  1834.  
  1835. As you can see, the winding shape fill causes QuickDraw GX to hide the inner loop—it fills in the entire polygon, outer loop and inner. 
  1836. It is possible, however, to define a polygon in such a way that QuickDraw GX does not fill the inner loop even when you specify the winding shape fill . Unlike the eve-odd shape fill, which never fills an inner loop, winding shape fill considers contour direction when filling a shape:
  1837. n    If the inner loop and the outer loop have the same contour direction, winding shape fill causes QuickDraw GX to fill the inner loop as well as the outer loop, as shown in Figure 2-32.
  1838. n    If the inner loop and the outer loop have opposite contour directions, winding shape fill causes QuickDraw GX to fill the outer loop, but not the inner loop. The next section gives an example using path shapes.
  1839. For more information about contour direction and shape-filling algorithms, see “Shape Fill” on page 2-10.
  1840. For more information about polygon shapes, see “Polygon Shapes” on page 2-20 and “Polygon Structures” on page 2-92.
  1841. For information about the functions you can use to create and draw polygons, see the description of the GXNewPolygons function on page 2-99 and the GXDrawPolygons function on page 2-137.
  1842. Creating and Drawing Paths
  1843.  
  1844. Like a polygon contour, a path contour is a series of connected points. However, whereas a polygon contour is made up of straight lines, a path contour can contain both straight lines and curves. Therefore, the geometric points that make up a path contour can be on-curve points or off-curve control points. QuickDraw GX defines the gxPath strucutre to encapsulate a path contour geometry:
  1845. struct gxPath {
  1846.     long                    vectors;
  1847.     long                    controlBits[gxAnyNumber];
  1848.     struct gxPoint             vector[gxAnyNumber];
  1849. };
  1850. The vectors field indicates the number of geometric points in the path and the vector array contains the geometric points themselves. The controlBits array specifies which geometric points are on-curve points and which are off-curve control points. A value of 0 indicates an on-curve point and a value of 1 indicates an off-curve point. For example, a controlBits field with the value
  1851. 0x55555555   /* 0101 0101 0101 0101 ... */
  1852. indicates that every other point is an off-curve control point; the first point is on curve, the second point is off, and so on. As another example, a controlBits field value of
  1853. 0x00000000   /* 0000 0000 0000 0000 ... */
  1854. indicates all points are on curve, which effectively creates a polygon.
  1855. Notice that the controlBits array allows you to specify sequential off-curve control points. For example, a controlBits value of 
  1856. 0xFFFFFFFF   /* 1111 1111 1111 1111 ... */
  1857. indicates that all control points are off curve. When you indicate that two control points in a row are off curve, QuickDraw GX assumes an on-curve point midway between them. (The example in Listing 2-17 on page 2-52 gives an example.)
  1858. Like the polygon shape, the path shape allows you to group any number of path contours within a single QuickDraw GX shape. The gxPaths structure encapsulates the multiple-path geometry:
  1859. truct gxPaths {
  1860.     long                  contours;
  1861.     struct gxPath             contour[gxAnyNumber];
  1862. };
  1863. The contours field indicates the total number of contours (in other words, the total number of separate paths), and the contour array contains the path geometries.
  1864. Creating Paths With a Single Contour
  1865.  
  1866. Since a gxPaths structure is variable length and every element in it is of type long, you can define a path geometry as an array of long values. The sample function in Listing 2-12 shows how to define a path geometry as an array of long values, and then draw a path shape using the GXDrawPaths function. Since the GXDrawPaths function expects its first parameter to be a pointer to a gxPaths structure, the sample function casts the array of long values to the appropriate type using the expression
  1867. (gxPaths *) aPathGeometry
  1868. before sending the information to the GXDrawPaths function.
  1869. Listing 2-16    Drawing a path shape
  1870.  
  1871. void DrawAPathShape(void)
  1872. {
  1873.     long aPathGeometry[] = {1, /* number of contours */
  1874.                                     6, /* number of points */
  1875.                                     0x48000000, /* 0100 1000 */
  1876.                                     ff(50), ff(100),   /* on curve */
  1877.                                     ff(0), ff(75),     /* off curve */
  1878.                                     ff(50), ff(50),    /* on curve */
  1879.                                     ff(150), ff(50),   /* on curve */
  1880.                                     ff(200), ff(75),   /* off curve */
  1881.                                     ff(150), ff(100)}; /* on curve */
  1882.                                           
  1883.     
  1884.     GXDrawPaths((gxPaths *) aPathGeometry, gxOpenFrameFill);
  1885. }
  1886. The path defined in this example has four on-curve points and two off-curve points. When drawn with the open-frame shape fill, it contains two curves and one straight line, as shown in Figure 2-33.
  1887. Figure 2-33    A path 
  1888.  
  1889. The sample function from Listing 2-16 draws the path without creating a path shape. It could instead create a path shape with the GXNewPaths function: 
  1890. aPathsShape = GXNewPaths((gxPaths *) aPathGeometry);
  1891. and then draw it using the GXDrawShape function:
  1892. GXDrawShape(aPathsShape);
  1893. You can also create path shapes using the GXNewShape function:
  1894. aPathsShape = GXNewShape(gxPathType);
  1895. GXSetPaths(aPathsShape, (gxPaths *) aPathGeometry);
  1896. or by using the GXNewShapeVector function:
  1897. aPathsShape = GXNewShapeVector(gxPathType, aPathGeometry);
  1898. Notice that in this case you do not have to cast the aPathGeometry array to be a pointer to a gxPaths structure. The GXNewShapeVector function expects an array of long values.
  1899. Although the GXDrawPaths function (shown in Listing 2-16) allows you to specify a shape fill, the GXDrawShape function does not. If you create a path shape and you want it to have a different shape fill than the default path shape, you must indicate the desired shape fill using the GXSetShapeFill function—for example, 
  1900. GXSetShapeFill(aPathsShape, gxInverseEvenOddFill);
  1901. For more information about shape fills, see “Shape Fill” on page 2-10.
  1902. Creating Paths Using Only Off-Curve Points
  1903.  
  1904. The sample function in Listing 2-17 shows how you can create a path using only off-curve control points. The path defined in this example contains four control points, and the controlBits field is set to
  1905. 0xF0000000    /* 1111 0000 0000 0000 0000 ... */
  1906. which indicates that the first four points are off curve. The path contains only four points, and therefore they are all off curve.
  1907. Listing 2-17    Creating a path using only off-curve control points
  1908.  
  1909. void CreateRoundPath(void)
  1910. {
  1911.     gxShape                aPathShape;
  1912.     
  1913.     long     aPathGeometry[] = {1, /* number of contours */
  1914.                                     4, /* number of points */
  1915.                                     0xF0000000, /* 1111 0000 ... */
  1916.                                     ff(50), ff(50),   /* off curve */
  1917.                                     ff(150), ff(50),  /* off curve */
  1918.                                     ff(150), ff(150), /* off curve */
  1919.                                     ff(50), ff(150)}; /* off curve */
  1920.                                           
  1921.         
  1922.     aPathShape = GXNewPaths((gxPaths *) aPathGeometry);
  1923.  
  1924.     GXDrawShape(aPathShape);
  1925. }
  1926. The four off-curve control points in this example form a square; the path that they define is a somewhat boxy circle, as shown in Figure 2-34.
  1927. Figure 2-34    A round path shape
  1928.  
  1929. Notice that the path is filled with the even-odd shape fill, which is the default for path shapes. You could, however, specify any shape fill for this path except the open-frame shape fill. The open-frame shape fill requires that the first and last points of the contour be on-curve points, and this path has no on-curve points.
  1930. Creating Paths With Multiple Contours
  1931.  
  1932. The sample function in Listing 2-13 shows how a single path shape can contain more than one path contour. The path shape defined in this example includes the round path from the previous example as well as a second round path, entirely contained within the first.
  1933. Listing 2-18    Creating a path with concentric contours
  1934.  
  1935. void CreateHollowCircles(void)
  1936. {
  1937.     gxShape            aPathShape;
  1938.     
  1939.     long aPathGeometry[] = {2, /* number of contours */
  1940.                                     4, /* number of points */
  1941.                                     0xF0000000,
  1942.                                     ff(50), ff(50),   /* off curve */
  1943.                                     ff(150), ff(50),  /* off curve */
  1944.                                     ff(150), ff(150), /* off curve */
  1945.                                     ff(50), ff(150),  /* off curve */
  1946.  
  1947.                                     4, /* number of points */
  1948.                                     0xF0000000,
  1949.                                     ff(65), ff(65),   /* off curve */
  1950.                                     ff(135), ff(65),  /* off curve */
  1951.                                     ff(135), ff(135), /* off curve */
  1952.                                     ff(65), ff(135)}; /* off curve */
  1953.                                     
  1954.         
  1955.     aPathShape = GXNewPaths((gxPaths *) aPathGeometry);
  1956.     GXSetShapeFill(aPathShape, gxClosedFrameFill);
  1957.  
  1958.     GXDrawShape(aPathShape);
  1959. }
  1960. The result of this function is shown in Figure 2-35.
  1961. Figure 2-35    A framed path shape with two concentric clockwise contours
  1962.  
  1963. You can change the shape fill of this polygon by removing this line of code from the sample function in Listing 2-18:
  1964. GXSetShapeFill(aPolygonsShape, gxClosedFrameFill);
  1965. If you don’t specify a shape fill, the GXNewPaths function uses the shape fill from the default path shape, which is the gxEvenOddFill shape fill (unless you change it using the GXGetDefaultShape and GXSetShapeFill functions). The path shape resulting from a gxEvenOddFill shape fill is shown in Figure 2-29.
  1966. Figure 2-36    An even-odd filled path shape with two concentric clockwise contours
  1967.  
  1968. Notice that the even-odd shape fill causes QuickDraw GX to fill in the outer contour, but not the inner contour. However, if you specify the winding shape fill for this path using the call
  1969. GXSetShapeFill(aPathShape, gxWindingFill);
  1970. the resulting shape would appear as shown in Figure 2-37.
  1971. Figure 2-37    A winding-filled path shape with two concentric clockwise contours
  1972.  
  1973. Unlike the even-odd shape fill, the winding shape fill causes QuickDraw GX to fill inner contours—as long as the inner contour has the same contour direction as the outer contour. If the inner contour and the outer contour have opposite contour directions, neither the even-odd shape fill nor the winding shape fill will fill the inner contour.
  1974. For example, if you change the direction of the inner contour from the previous example by reversing the order of the second path’s geometric points, as in the declaration
  1975. static long         aPathGeometry[] = {2, /* number of contours */
  1976.                                         4, /* number of points */
  1977.                                         0xF0000000, /* 1111 0000 */
  1978.                                         ff(50), ff(50),    /* off */ 
  1979.                                         ff(150), ff(50),   /* off */ 
  1980.                                         ff(150), ff(150),  /* off */ 
  1981.                                         ff(50), ff(150),   /* off */ 
  1982.  
  1983.                                         4, /* number of points */
  1984.                                         0xF0000000, /* 1111 0000 */
  1985.                                         ff(65), ff(135),   /* off */ 
  1986.                                         ff(135), ff(135),  /* off */ 
  1987.                                         ff(135), ff(65),   /* off */ 
  1988.                                         ff(65), ff(65)};   /* off */
  1989. and set the shape fill to the closed-frame shape fill using the call
  1990. GXSetShapeFill(aPathShape, gxClosedFrameFill);
  1991. the resulting shape has contours with opposite contour directions, as depicted in
  1992. Figure 2-38.
  1993. Figure 2-38    A framed paths shape with an internal counterclockwise contour
  1994.  
  1995. Since the outer contour and the inner contour have opposite contour directions, neither the even-odd shape fill nor the winding shape fill cause QuickDraw GX to fill the inner contour, as shown in Figure 2-39.
  1996. Figure 2-39    A filled path shape with an internal counterclockwise contour
  1997.  
  1998. For more information about contour direction and shape-filling algorithms, see “Shape Fill” on page 2-10.
  1999. For more information about path shapes, see “Path Shapes” on page 2-23 and “Path Structures” on page 2-93.
  2000. For information about the functions you can use to create and draw paths, see the description of the GXNewPaths function on page 2-101 and the GXDrawPaths function on page 2-138.
  2001. Converting Shapes to Points, Lines, and Rectangles
  2002.  
  2003. QuickDraw GX provides the GXGetShapeType and GXSetShapeType functions to allow you to manipulate a shape’s type. The GXGetShapeType function simply returns the value of the shape type property for a specified shape. For geometric shapes, the possible values returned from this function are:
  2004. n    gxEmptyType 
  2005. n    gxFullType 
  2006. n    gxPointType 
  2007. n    gxLineType 
  2008. n    gxCurveType 
  2009. n    gxRectangleType 
  2010. n    gxPolygonType 
  2011. n    gxPathType 
  2012. The GXSetShapeType function allows you to change the shape type of an existing shape. In doing so, this function often has to reinterpret the geometry of the shape. This reinterpretation is called type conversion. 
  2013. Sometimes converting between shape types causes no loss of information. For example, if you convert a rectangle shape to a polygon shape, the resulting polygons shape retains all of the geometry information in the original rectangle. In this case, QuickDraw GX creates a polygon geometry containing a single contour with four geometric points.
  2014. However, in some cases converting between shape types does cause a loss of information. For example, if you convert a path shape to a rectangle shape, QuickDraw GX sets the rectangle geometry to be bounds of the original path shape—the rest of the information in the original path geometry is lost.
  2015. In general, when converting between geometric shape types, QuickDraw GX exhibits different behavior in these four situations:
  2016. n    when converting a geometric shape to an empty shape or full shape
  2017. n    when converting a geometric shape to a point, line, or rectangle
  2018. n    when converting a geometric shape to a curve
  2019. n    when converting a geometric shape to a polygon or path
  2020. When converting any shape to an empty shape or full shape, all of the geometric information in the original shape is lost.
  2021. This rest of this section gives some examples of the second case: converting to points, lines, and rectangles. The next two sections give examples of the other two cases.
  2022. Note
  2023. You can also use the GXSetShapeType function to convert between geometric shapes and bitmaps, pictures, and typographic shapes. For examples, see Chapters 5 and 6, “Bitmaps,” and “Pictures,” in this book, and the chapter “Typographic Shapes” in Inside Macintosh: QuickDraw GX Typography.u
  2024. When converting a shape to a point, line, or rectangle, QuickDraw GX uses the bounding rectangle of the original shape (bounding rectangles are defined in the chapter “Geometric Operations” in this book. For an example, see Figure 2-41 on page 2-60.):
  2025. n    When you convert to a rectangle shape, the resulting rectangle is the bounding rectangle of the original shape. 
  2026. n    When you convert to a line shape, the result is a line that runs from the upper-left corner of the orignal shape’s bounding rectangle to the lower-right corner.
  2027. n    When you convert to a point, the resulting point is the point at the upper-left corner of the bounding rectangle of the original shape.
  2028. Listing 2-19 creates a path shape, which is converted first to a rectangle shape, then to a line shape, and finally to a point shape later in this section.
  2029. Listing 2-19    Creating a figure-eight path shape
  2030.  
  2031. void CreateFigureEight(void)
  2032. {
  2033.     gxShape                aPathShape;
  2034.     
  2035.     static long                figureEightGeometry[] = {1,/* number of contours */
  2036.                                                          4, /* number of points */
  2037.                                                         0xF0000000, 
  2038.                                                         ff(50), ff(50),  /* off */
  2039.                                                          ff(200),ff(200), /* off */
  2040.                                                          ff(50), ff(200), /* off */
  2041.                                                          ff(200),ff(50)}; /* off */
  2042.         
  2043.     aPathShape = GXNewPaths((gxPaths *) figureEightGeometry);
  2044.     GXSetShapeFill(aPathShape, gxHollowFill);
  2045.  
  2046.     GXDrawShape(aPathShape);
  2047. }
  2048. The resulting path geometry is shown in Figure 2-40.
  2049. Figure 2-40    A figure-eight path shape
  2050.  
  2051. If you convert this shape to a rectangle shape, using the call
  2052. GXSetShapeType(aPathShape, gxRectangleType);
  2053. the resulting shape is the bounding rectangle for the original path shape, as shown in Figure 2-41.
  2054. Figure 2-41    The result of converting a path shape to a rectangle shape
  2055.  
  2056. If you convert the original path shape to a line shape, using the call
  2057. GXSetShapeType(aPathShape, gxLineType);
  2058. the resulting shape is a diagonal line from the upper-left corner of the path’s bounding rectangle to its lower-right corner, as shown in Figure 2-42. 
  2059. Figure 2-42    The result of converting a path shape to a line shape
  2060.  
  2061. Finally, if you convert the orignal path shape to a point shape, using the call
  2062. GXSetShapeType(aPathShape, gxPointType);
  2063. the resulting shape is the point at the upper-left corner of the path’s bounding rectangle, as shown in Figure 2-43.
  2064. Figure 2-43    A path shape converted to a point shape
  2065.  
  2066. The next two sections give examples of converting to the curve shape type and of converting to the polygon and path shape types.
  2067. For more information about the GXSetShapeType function in general, see the chapter “Shape Objects” of Inside Macintosh: QuickDraw GX Objects.
  2068. Converting Shapes to Curve Shapes
  2069.  
  2070. When converting a geometric shape to a curve shape, QuickDraw GX takes one of these approaches:
  2071. n    When converting a point to a curve, QuickDraw GX sets each of the three geometric points of the curve to be the same as the original point.
  2072. n    When converting a line to a curve, QuickDraw GX sets the first point and last point of the curve to be the same as the first point and last point of the line and sets the off-curve control point to be same as the last point of the line, which results in the curve being a straight line.
  2073. n    When converting a rectangle to a curve, QuickDraw GX sets the first point of the curve to be the upper-left corner of the rectangle and the last point of the curve to be the lower-right corner of the rectangle. The off-curve control point is set to be the same as the last point, which results in the curve being a straight line.
  2074. n    When converting a polygon or a path to a curve, QuickDraw GX sets the three geometric points of the curve to be the first three geometric points of the original shape.
  2075. The sample function in Listing 2-20 creates a line shape and converts it to a curve.
  2076. Listing 2-20    Converting a line to a curve
  2077.  
  2078. void ConvertLineToCurve(void)
  2079. {
  2080.     gxShape                   aLineShape;
  2081.     
  2082.     static gxLine     diagonalGeometry = {ff(50), ff(50),
  2083.                                                  ff(150), ff(150)};
  2084.  
  2085.         
  2086.     aLineShape = GXNewLine(&diagonalGeometry);
  2087.     GXSetShapeType(aLineShape, gxCurveType);
  2088.     
  2089.     GXDrawShape(aLineShape);
  2090. }
  2091. The original line shape and the resulting curve shape are shown in Figure 2-44.
  2092. Figure 2-44    A line shape before and after conversion to a curve shape
  2093.  
  2094. Notice that the converted curve looks just like the original line. The only difference between the two shapes is that the curve shape has an additional off-curve control point, which is set to be identical to the last point.
  2095. The sample function in Listing 2-21 creates a rectangle shape and converts it to a curve shape.
  2096. Listing 2-21    Converting a rectangle to a curve
  2097.  
  2098. void ConvertRectangleToCurve(void)
  2099. {
  2100.     gxShape         aRectangleShape;
  2101.     
  2102.     static gxRectangle  rectangleGeometry = {ff(50), ff(50),
  2103.                                                                ff(150), ff(150)};
  2104.  
  2105.         
  2106.     aRectangleShape = GXNewRectangle(&rectangleGeometry);
  2107.     GXSetShapeType(aRectangleShape, gxCurveType);
  2108.  
  2109.     GXDrawShape(aRectangleShape);
  2110. }
  2111. The original rectangle and the resulting curve are both shown in Figure 2-45.
  2112. Figure 2-45    A rectangle shape before and after conversion to a curve shape
  2113.  
  2114. As in the previous example, the off-curve control point of the curve shape is set to be the same as the last point, which results in the curve shape being a straight line.
  2115. The next example, shown in Listing 2-22, shows how QuickDraw GX converts a polygon shape to a curve shape. 
  2116. Listing 2-22    Converting a polygon shape to a curve shape
  2117.  
  2118. void ConvertPolygonToCurve(void)
  2119. {
  2120.     gxShape         aPolygonShape;
  2121.     
  2122.     static long     aPolygonGeometry[] = {1, /* number of contours */
  2123.                                                     4, /* number of points */
  2124.                                                     ff(50), ff(50),   
  2125.                                                    ff(150), ff(50), 
  2126.                                                    ff(150), ff(150), 
  2127.                                                     ff(50), ff(150)};
  2128.  
  2129.         
  2130.     aPolygonShape = GXNewPolygons((gxPolygons *) aPolygonGeometry);
  2131.     GXSetShapeType(aPolygonShape, gxCurveType);
  2132.  
  2133.     GXDrawShape(aPolygonShape);
  2134. }
  2135. In this example, QuickDraw GX sets the three geometric points of the resulting curve to be the first three geometric points of the original polygon. (Converting from path shapes to curves shapes works in the same way.) The original polygon and the resulting curve are shown in Figure 2-46. 
  2136. Figure 2-46    A polygon shape before and after conversion to a curve shape
  2137.  
  2138. Notice that, even though the polygon in this example looks the same as the rectangle in Figure 2-45, the converted curve shape looks quite different.
  2139. The next section gives examples of converting shapes to polygon and path shapes. 
  2140. For more information about the GXSetShapeType function in general, see the chapter “Shape Objects” of Inside Macintosh: QuickDraw GX Objects.
  2141. Converting Shapes to Polygons and Paths
  2142.  
  2143. When converting other geometric shapes to polygon or path shapes, the original shapes don’t lose any geometric information. For example, when you convert a line shape to a path shape, the resulting paths shape contains one contour with two geometric points, both on curve—an exact duplicate of the original line. 
  2144. You can even convert a curve shape to a polygon shape without losing geometric information, althought the result does draw differently. The resulting polygon has one contour and three geometric points—the same three geometric points as the original curve. If you convert the polygon back to a curve, you end up with the original curve.
  2145. When you convert a rectangle shape to a polygon shape, as shown in Listing 2-23, the original shape and the resulting shape look exactly the same.
  2146. Listing 2-23    Converting a rectangle shape to a polygon shape
  2147.  
  2148. void ConvertRectangleToPolygon(void)
  2149. {
  2150.     gxShape aRectangleShape;
  2151.     
  2152.     static gxRectangle  rectangleGeometry = {ff(50), ff(50),
  2153.                                                                ff(150), ff(150)};
  2154.  
  2155.         
  2156.     aRectangleShape = GXNewRectangle(&rectangleGeometry);
  2157.     GXSetShapeType(aRectangleShape, gxPolygonType);
  2158.  
  2159.     GXDrawShape(aRectangleShape);
  2160. }
  2161. The original rectangle and the resulting polygon are shown in Figure 2-47.
  2162. Figure 2-47    A rectangle shape before and after conversion to a polygon shape
  2163.  
  2164. Converting from a path shape to a polygon shape, however, does lose geometric information. The resulting polygon contains the same geometric points as the original path; however, the points are all considered on-curve points. The original information about which points were on curve and which points were off curve is lost during this conversion.
  2165. As an example, Listing 2-24 creates a path shape and converts it to a polygon shape.
  2166. Listing 2-24    Converting a path shape to a polygon shape
  2167.  
  2168. void ConvertPathToPolygon(void)
  2169. {
  2170.     gxShape            aPathShape;
  2171.     
  2172.     static long                figureEightGeometry[] = {1, /* # of contours */
  2173.                                                         4, /* # of points */
  2174.                                                         0xF0000000, 
  2175.                                                        ff(50), ff(50),  /* off */
  2176.                                                          ff(200),ff(200), /* off */
  2177.                                                          ff(50), ff(200), /* off */
  2178.                                                          ff(200),ff(50)}; /* off */
  2179.  
  2180.         
  2181.     aPathShape = GXNewPaths((gxPaths *) figureEightGeometry);
  2182.     GXSetShapeFill(aPathShape, gxHollowFill);
  2183.     GXSetShapeType(aPathShape, gxPolygonType);
  2184.  
  2185.     GXDrawShape(aPathShape);
  2186. }
  2187. Figure 2-48 shows the original path shape and the resulting polygon shape.
  2188. Figure 2-48    A path shape before and after conversion to a polygon shape
  2189.  
  2190. Note
  2191. You can request that QuickDraw GX calculate a better polygon approximation to a path by setting the curve error property of the path shape’s style object before calling the GXSetShapeType function. See the next chapter, “Geometric Styles,” for examples.u
  2192. Converting in the other direction, however—from a polygon shape to a path shape—retains all of the geometry information and the resulting path shape looks exactly the same as the original polygon shape. The sample function in Listing 2-25 gives an example.
  2193. Listing 2-25    Converting a polygon shape to a path shape
  2194.  
  2195. void ConvertPolygonToPath(void)
  2196. {
  2197.     gxShape                aPolygonsShape;
  2198.     
  2199.     static long                aPolygonsGeometry[] = {2, /* number of contours */
  2200.                                                      3, /* number of points */
  2201.                                                     ff(50), ff(50),   
  2202.                                                          ff(100), ff(80), 
  2203.                                                          ff(50), ff(110),
  2204.                                                      3, /* number of points */
  2205.                                                      ff(200), ff(50),   
  2206.                                                          ff(150), ff(80), 
  2207.                                                          ff(200), ff(110)};
  2208.                                           
  2209.     
  2210.     aPolygonsShape = GXNewPolygons((gxPolygons *)
  2211.                                              aPolygonsGeometry);
  2212.     GXSetShapeType(aPolygonsShape, gxPathType);
  2213.     
  2214.     GXDrawShape(aPolygonsShape);
  2215. }
  2216. The original polygon shape and the converted path shape are shown in Figure 2-49.
  2217. Figure 2-49    Polygon shape with two contours before and after conversion to a path shape
  2218.  
  2219. For more information about the GXSetShapeType function in general, see the chapter “Shape Objects” of Inside Macintosh: QuickDraw GX Objects
  2220. For information about converting between geometric shapes and bitmaps, see Chapter 5, “Bitmaps,” in this book. For information about converting between geometric shapes and pictures, see Chapter 6, “Pictures,” in this book.
  2221. For information about converting between geometric shapes and typographic shapes, see Inside Macintosh: QuickDraw GX Typography.
  2222. Replacing Geometric Points
  2223.  
  2224. The GXSetPoint, GXSetLine, GXSetCurve, GXSetRectangle, GXSetPolygons, and GXSetPaths functions allow you to replace the geometry of an existing shape. The limitation of these functions is that you must replace the entire geometry at once.
  2225. QuickDraw GX provides other, more sophisticated, mechanisms for editing shape geometries. The GXSetShapePoints function, which is illustrated in this section, allows you to replace individual geometric points within a shape’s geometry. The GXSetPolygonParts, GXSetPathParts, and GXSetShapeParts functions, which are discussed in the next three sections, provide even more ways to edit the geometries of shapes.
  2226. The sample function in Listing 2-26 creates a path shape and uses the GXSetShapePoints function to replace two of the path’s geometric points.
  2227. Listing 2-26    Replacing geometric points 
  2228.  
  2229. void ReplaceTopTwoControlPoints(void)
  2230. {
  2231.     gxShape             aPathsShape;
  2232.  
  2233.     static long     twoCurveGeometry[] = {1, /* number of contours */
  2234.                                                    6, /* number of points */
  2235.                                                    0x48000000,/* control bits */
  2236.                                                    ff(100), ff(150),  /* on */
  2237.                                                    ff(50),  ff(100),      /* off */
  2238.                                                    ff(100), ff(50),   /* on */
  2239.                                                    ff(200), ff(50),   /* on */
  2240.                                                    ff(250), ff(100),  /* off */
  2241.                                                    ff(200), ff(150)}; /* on */
  2242.                                           
  2243.                                           
  2244.     static gxPoint     newTopGeometry[] = {ff(140), ff(50), 
  2245.                                                 ff(160), ff(50)}; 
  2246.  
  2247.  
  2248.     aPathsShape = GXNewPaths((gxPaths *) twoCurveGeometry);
  2249.     GXSetShapeFill(aPathsShape, gxOpenFrameFill);
  2250.     
  2251.     GXSetShapePoints(aPathsShape, 3, 2, newTopGeometry);
  2252.  
  2253.     GXDrawShape(aPathsShape);
  2254. }
  2255. The GXSetShapePoints function takes four parameters:
  2256. n    a reference to the shape to edit
  2257. n    the index of the first geometric point to be replaced
  2258. n    the number of geometric points to replace
  2259. n    an array containing the new geometric points
  2260. Therefore, the line of code from the sample function in Listing 2-26
  2261. GXSetShapePoints(aPathsShape, 3, 2, newTopGeometry);
  2262. replaces the third and fourth geometric point from the original path shape with the two geometric points in the newTopGeometry array.
  2263. Figure 2-50 shows the path shape before the geometric points are replaced. (The geometric indexes of the points are also shown.)
  2264. Figure 2-50    A paths shape with a flat top
  2265.  
  2266. Figure 2-51 shows the path shape after the geometric points are replaced. (The geometric indexes of the points are also shown.)
  2267. Figure 2-51    A paths shape with geometric points replaced
  2268.  
  2269. For more information about the GXSetShapePoints function, see page 2-121.
  2270. The next three sections give examples of functions that allow you even more control in editing the geometric points of a shape’s geometry.
  2271. Editing Polygon Parts
  2272.  
  2273. QuickDraw GX provides six functions that allow sophisticated editing of geometric shapes:
  2274. n    The GXGetPolygonParts and GXSetPolygonParts functions allow you to extract information from a polygon geometry, replace information in the geometry, remove information in the geometry, and insert new information in the geometry.
  2275. n    The GXGetPathParts and GXSetPathParts functions allow you to extract, replace, remove, and insert information in a path shape’s geometry.
  2276. n    The GXGetShapeParts and GXSetShapeParts functions allow you to extract, replace, remove, and insert information in any shape’s geometry.
  2277. This section gives examples of the GXGetPolygonParts and GXSetPolygonParts functions. The next two sections show how to edit path shape geometries and shape geometries in general.
  2278. Listing 2-27 creates a polygon shape with two contours. Later examples in this section use this polygon shape to demonstrate editing polygon parts.
  2279. Listing 2-27    Creating a polygon shape with two contours
  2280.  
  2281. void CreateTwoAngles(void)
  2282. {
  2283.     gxShape                 aPolygonsShape;
  2284.  
  2285.     static long     twoAngleGeometry[] = {2, /* number of contours */
  2286.                                                    3, /* number of points */
  2287.                                                    ff(100), ff(150), 
  2288.                                                    ff(50), ff(100), 
  2289.                                                    ff(100), ff(50),
  2290.                                                    3, /* number of points */
  2291.                                                    ff(200), ff(50), 
  2292.                                                    ff(250), ff(100), 
  2293.                                                    ff(200), ff(150)};    
  2294.         
  2295.  
  2296.     aPolygonsShape = GXNewPolygons((gxPolygons *) 
  2297.                                              twoAngleGeometry);
  2298.     GXSetShapeFill(aPolygonsShape, gxOpenFrameFill);
  2299.  
  2300.     GXDrawShape(aPolygonsShape);
  2301. }
  2302. The result of this sample function is shown in Figure 2-52. (This figure also shows the geometric indexes of the geometric points. Geometric indexes indicate the order of the points throughout the entire geometry—unlike contour indexes, geometric indexes do not restart at 1 for each contour.)
  2303. Figure 2-52    A polygon shape with two contours
  2304.  
  2305. The GXGetPolygonParts function allows you to extract geometric points from the geometry of an existing polygon shape into a new polygon geometry. This function takes four parameters:
  2306. n    a reference to the existing polygon shape
  2307. n    the index of the first desired geometric point
  2308. n    the number of geometric points to include
  2309. n    a pointer to a polygon geometry in which to store the extracted geometric points
  2310. The GXGetPolygonParts function returns as its function result the number of bytes necessary to contain the extracted polygon. Therefore, you typically call GXGetPolygonParts twice—once to determine the size of extracted polygon and once to extract the polygon. For example, if you declare the variable
  2311. long             byteCount;
  2312. you could determine the number of bytes necessary to extract the top half of the polygon geometry in Figure 2-52 using this line of code:
  2313. byteCount = GXGetPolygonParts(aPolygonsShape, 2, 4, nil);
  2314. In this example, setting the final parameter to nil indicates that you want to determine the number of bytes necessary to hold the extracted polygon geometry, but you do not want to actually extract the polygon geometry. The values of 2 and 4 for the second and third parameters indicate that the GXGetPolygonParts function should determine the number of bytes necessary to hold an extracted polygon geometry that contains geometric points 2, 3, 4, and 5 from the polygon geoemtry in Figure 2-52.
  2315. You can then use this byte count to allocate enough memory to hold the extracted polygon geometry:
  2316. gxPolygons                *topHalfGeometry;    
  2317. topHalfGeometry = (gxPolygons *) NewPtr(byteCount);
  2318. Finally, you can extract the polygons geometry by calling GXGetPolygonParts again:
  2319. GXGetPolygonParts(aPolygonsShape, 2, 4, topHalfGeometry);
  2320. The sample function in Listing 2-28 creates the polygon shape from the previous example, extracts the second through the fifth geometric points and puts them into a separate geometry, and then replaces the geometry of the orignial polygon shape with the extracted geometry.
  2321. Listing 2-28    Extracting part of a polygons shape
  2322.  
  2323. void ExtractTopPartOfPolygon(void)
  2324. {
  2325.     gxShape                 aPolygonsShape;
  2326.  
  2327.     static long     twoAngleGeometry[] = {2, /* number of contours */
  2328.                                                   3, /* number of points */
  2329.                                                   ff(100), ff(150),
  2330.                                                   ff(50), ff(100),
  2331.                                                   ff(100), ff(50),
  2332.                                                   3, /* number of points */
  2333.                                                   ff(200), ff(50),
  2334.                                                   ff(250), ff(100),
  2335.                                                   ff(200), ff(150)};
  2336.  
  2337.     long            byteCount;
  2338.  
  2339.     gxPolygons             *topHalfGeometry;    
  2340.  
  2341.     aPolygonsShape = GXNewPolygons((gxPolygons *) 
  2342.                                              twoAngleGeometry);
  2343.     GXSetShapeFill(aPolygonsShape, gxOpenFrameFill);
  2344.  
  2345.     byteCount =  GXGetPolygonParts(aPolygonsShape, 2, 4, nil);
  2346.     topHalfGeometry = (gxPolygons *) NewPtr(byteCount);
  2347.     GXGetPolygonParts(aPolygonsShape, 2, 4, topHalfGeometry);
  2348.  
  2349.     GXSetPolygons(aPolygonsShape, topHalfGeometry);
  2350.  
  2351.     GXDrawShape(aPolygonsShape);
  2352. }
  2353. The resulting polygon shape is shown in Figure 2-53. (The geometric indexes of the geometric points are also shown.)
  2354. Figure 2-53    A polygon shape extracted from a larger polygon shape
  2355.  
  2356. Compare this polygon shape with the polygon shape shown in Figure 2-52.
  2357. Like the GXSetShapePoints function discussed in the previous section, the GXSetPolygonParts function also allows you to replace geometric points within a polygon shape’s geometry. However, the GXSetPolygonParts function allows you even more editing control. With it, you can also remove geometric points, insert geometric points, and break a polygon shape into multiple contours.
  2358. As an example of replacing geometric points in a polygon geometry, the sample function in Listing 2-29 creates two polygon geometries: the two-angle polygon geometry from Figure 2-52 and another polygon geometry consisting of a single point. The sample function creates the two-angle polygon shape as in Listing 2-27 and then replaces its third and fourth geometric points with the single geometric point of the other polygon 
  2359. geometry.
  2360. Listing 2-29    Replacing geometric points of a polygons shape
  2361.  
  2362. void ReplaceControlPoints(void)
  2363. {
  2364.     gxShape                 aPolygonsShape;
  2365.  
  2366.     static long     twoAngleGeometry[] = {2, /* number of contours */
  2367.                                                    3, /* number of points */
  2368.                                                    ff(100), ff(150), 
  2369.                                                    ff(50), ff(100), 
  2370.                                                    ff(100), ff(50),
  2371.                                                    3, /* number of points */
  2372.                                                    ff(200), ff(50), 
  2373.                                                    ff(250), ff(100), 
  2374.                                                    ff(200), ff(150)};    
  2375.                                           
  2376.     static long         newTopGeometry[] = {1, /* number of contours */
  2377.                                               1, /* number of points */
  2378.                                               ff(150), ff(50)};
  2379.         
  2380.  
  2381.     aPolygonsShape = GXNewPolygons((gxPolygons *) 
  2382.                                              twoAngleGeometry);
  2383.     GXSetShapeFill(aPolygonsShape, gxOpenFrameFill);
  2384.  
  2385.     GXSetPolygonParts(aPolygonsShape, 3, 2, 
  2386.                            (gxPolygons *) newTopGeometry,
  2387.                             gxBreakNeitherEdit);
  2388.  
  2389.     GXDrawShape(aPolygonsShape);
  2390. }
  2391. Figure 2-54 shows the result of the sample function in Listing 2-29.
  2392. Figure 2-54    A polygon with two geometric points replaced by a single geometric point
  2393.  
  2394. Notice that, whereas the GXSetShapePoints function limited you to replacing geometric points on a point-by-point basis, the GXSetPolygonParts function allows you to replace any number of geometric points in the original geometry with any number of new geometric points contained in an arbitrary polygon geometry.
  2395. Since the GXSetPolygonParts function allows you to insert an arbitrary polygon geometry into the geometry of an existing polygon shape, you can use this function to break a single polygon contour into multiple contours. In fact, the final parameter to GXSetPolygonParts allows you to specify how the resulting polygons shape should be broken up. In the previous example, the gxBreakNeitherEdit constant indicated that the resulting polygon should not be broken into separate contours.
  2396. The next example, shown in Listing 2-30, first creates a polygons shape similar to the two-angle polygons shape, except in this example the two contours are connected, as shown in Figure 2-55.
  2397. Figure 2-55    A closed-frame filled polygon
  2398.  
  2399. The sample function then uses the GXSetPolygonParts function to insert a new geometric point in the center of the polygon. 
  2400. Listing 2-30    Creating a hollow polygon
  2401.  
  2402. void CreateHollowPolygon(void)
  2403. {
  2404.     gxShape                 aPolygonsShape;
  2405.  
  2406.     static long     twoAngleGeometry[] = {1,
  2407.                                                    6,
  2408.                                                   ff(100), ff(150), 
  2409.                                                    ff(50), ff(100), 
  2410.                                                    ff(100), ff(50),
  2411.                                                    ff(200), ff(50), 
  2412.                                                    ff(250), ff(100), 
  2413.                                                    ff(200), ff(150)};    
  2414.                                           
  2415.     static long                newCenterGeometry[] = {1,
  2416.                                                      1,
  2417.                                                      ff(150), ff(100)};
  2418.         
  2419.  
  2420.     aPolygonsShape = GXNewPolygons((gxPolygons *) 
  2421.                                              twoAngleGeometry);
  2422.     GXSetShapeFill(aPolygonsShape, gxClosedFrameFill);
  2423.  
  2424.     GXSetPolygonParts(aPolygonsShape, 4, 0, 
  2425.                             (gxPolygons *) newCenterGeometry,
  2426.                             gxBreakNeitherEdit);
  2427.  
  2428.     GXDrawShape(aPolygonsShape);
  2429. }
  2430. Since this sample function specifies the gxBreakNeitherEdit constant as the final parameter to the GXSetPolygonParts function, the resulting polygon has a single contour, as shown in Figure 2-56.
  2431. Figure 2-56    A polygon shape edited with the gxBreakNeitherEdit flag set
  2432.  
  2433. However, if the sample function had specified the gxBreakLeftEdit constant, as with the call
  2434. GXSetPolygonParts(aPolygonsShape, 4, 0, 
  2435.                       (gxPolygons *) newCenterGeometry, 
  2436.                       gxBreakLeftEdit);
  2437. QuickDraw GX would break the resulting polygon into two contours: The gxBreakLeftEdit constant indicates that the polygon should be broken between the newly inserted point and the previous point, as shown in Figure 2-57.
  2438. Figure 2-57    A polygon shape edited with the breakLeftEdit flag set
  2439.  
  2440. The gxBreakRightEdit constant works similarly, except the break occurs between the newly inserted point and the subsequent point, as shown in Figure 2-58.
  2441. Figure 2-58    A polygons shape edited with the breakRightEdit flag set
  2442.  
  2443. You can use the GXSetPolygonParts function to insert a polygon geometry that contains multiple contours. In this case, the breaks that occur in the inserted geometry remain in the resulting polygon shape.
  2444. For more information about polygon geometries, see “Polygon Shapes” on page 2-20.
  2445. For more information about the GXGetPolygonParts and GXSetPolygonParts functions, see the function descriptions on page 2-122 and page 2-123.
  2446. The next two sections show more examples of editing shape geometries.
  2447. Editing Paths Parts
  2448.  
  2449. The GXGetPathParts and GXSetPathParts functions work similarly to the GXGetPolygonParts and GXSetPolygonParts functions, which are described in the previous section.
  2450. The sample function in Listing 2-31 creates a paths shape similar to the polygons shape from the previous section. Later examples in this section use this path shape to demonstrate editing path parts.
  2451. Listing 2-31    Creating a path shape with two curved contours
  2452.  
  2453. void CreateTwoCurves(void)
  2454. {
  2455.     gxShape             aPathsShape;
  2456.  
  2457.     static long     twoCurveGeometry[] = {2, /* number of contours */
  2458.                                                   3, /* number of points */
  2459.                                                   0x40000000,
  2460.                                                  ff(100), ff(150), /* on */
  2461.                                                  ff(50), ff(100),      /* off */
  2462.                                                   ff(100), ff(50),  /* on */
  2463.                                                   3, /* number of points */
  2464.                                                   0x40000000,
  2465.                                                   ff(200), ff(50),   /* on */
  2466.                                                   ff(250), ff(100),  /* off */
  2467.                                                   ff(200), ff(150)}; /* on     */
  2468.         
  2469.  
  2470.     aPathsShape = GXNewPaths((gxPaths *) twoCurveGeometry);
  2471.     GXSetShapeFill(aPathsShape, gxOpenFrameFill);
  2472.  
  2473.     GXDrawShape(aPathsShape);
  2474. }
  2475. The resulting paths shape is shown in Figure 2-59.
  2476. Figure 2-59    A paths shape with two curved contours
  2477.  
  2478. You can use the GXSetPathParts function to replace any number of geometric points from this path shape with an arbitrary number of new geometric points. In a manner similar to the GXSetPolygonParts function, the GXSetPathParts function requires that you encapsulate the new geometric points in a path geometry. For example, to replace the top two geometric points in the path shape shown in Figure 2-59 with a single geometric point, you must first encapsulate the new geoemtric point in a path geometry, as with the definition
  2479. static long newTopGeometry[] = {1, /* number of contours */
  2480.                                           1, /* number of points */
  2481.                                           0x00000000,
  2482.                                           ff(150), ff(50)}; /* on curve */
  2483. and then call the GXSetPathParts function:
  2484. GXSetPathParts(aPathsShape, 3, 2, 
  2485.                     (gxPaths *) newTopGeometry, gxBreakNeitherEdit);
  2486. The resulting path shape is shown in Figure 2-60.
  2487. Figure 2-60    A path shape edited with GXSetPathParts
  2488.  
  2489. For more information about path geometries, see “Path Shapes” beginning on page 2-23.
  2490. For more information about the GXGetPathParts and GXSetPathParts functions, see the function descriptions on page 2-126 and page 2-127.
  2491. Editing Shape Parts
  2492.  
  2493. The GXSetShapeParts function is more general than the GXSetPolygonParts and GXSetPathParts functions described in the previous two sections. The GXSetShapeParts function allows you to replace a subset of the geometric points in one shape with the geometric points in the geometry of another shape.
  2494. For example, with GXSetShapeParts you could replace the last three geometric points of a polygon shape with the geometry of a line shape, or you could replace the first geometric point of a path shape with the entire geometry of a polygon shape.
  2495. The sample function in Listing 2-32 creates a path shape with one contour. Later examples in this section use this path shape to demonstrate editing shape parts.
  2496. Listing 2-32    Creating a path shape with one contour
  2497.  
  2498. void CreatePathShape(void)
  2499. {
  2500.     gxShape             aPathsShape;
  2501.  
  2502.     static long     twoCurveGeometry[] = {1, /* number of contours */
  2503.                                                   6, /* number of points */
  2504.                                                  0x48000000, /* 0100 1000 */
  2505.                                                   ff(100), ff(150),  /* on */
  2506.                                                   ff(50),  ff(100),      /* off */
  2507.                                                   ff(100), ff(50),   /* on */
  2508.                                                   ff(200), ff(50),   /* on */
  2509.                                                   ff(250), ff(100),  /* off */
  2510.                                                   ff(200), ff(150)}; /* on     */
  2511.  
  2512.     aPathsShape = GXNewPaths((gxPaths *) twoCurveGeometry);
  2513.     GXSetShapeFill(aPathsShape, gxOpenFrameFill);
  2514.  
  2515.     GXDrawShape(aPathsShape);
  2516. }
  2517. The resulting shape is shown in Figure 2-61.
  2518. Figure 2-61    A path shape with a flat top
  2519.  
  2520. To insert a new geometric point in this shape using the GXSetShapeParts function, you must first encapsulate the new geometric point in a point shape:
  2521. static gxPoint                 newTopGeometry = {ff(150), ff(20)}; 
  2522. gxShape aPointShape;
  2523. aPointShape = GXNewPoint(&newTopGeometry);
  2524. Then you must call the GXSetShapeParts function:
  2525. GXSetShapeParts(aPathsShape, 4, 0, aPointShape, 
  2526.                      gxBreakNeitherEdit);    
  2527. Since you must create a shape to encapsulate the point geometry, you should dispose ofthis shape when you no longer need it:
  2528. GXDisposeShape(aPointShape);
  2529. The resulting path shape is shown in Figure 2-62.
  2530. Figure 2-62    A path shape edited to have a pointy top
  2531.  
  2532. You can also use the GXSetShapeParts function to insert an off-curve control point in the path shape. To do this, however, you must encapsulate the new geometric point into a paths shape, because only a paths shape can contain a single off-curve point.
  2533. gxShape aSingleOffCurvePoint;
  2534. static long newTopGeometry[] = {1, /* number of contours */
  2535.                                          1, /* number of points */
  2536.                                          0xF0000000, /* all off curve */
  2537.                                          ff(150), ff(20)}; /* off curve */
  2538.  
  2539.  
  2540. aSmallPathsShape = GXNewPaths((gxPaths *) newTopGeometry);
  2541. GXSetShapeParts(aPathsShape, 4, 0, 
  2542.                     aSingleOffCurvePoint, gxBreakNeitherEdit);    
  2543. GXDisposeShape(aSmallPathsShape);
  2544. The resulting path shape is shown in Figure 2-63.
  2545. Figure 2-63    A paths shape edited to have a round top
  2546.  
  2547. The GXSetShapeParts function allows you to edit the geometry of any shape. For example, the sample function in Listing 2-33 creates a line shape and uses GXSetShapeParts to change the last point.
  2548. Listing 2-33    Creating a diagonal line
  2549.  
  2550. void CreateDiagonalLine(void)
  2551. {
  2552.     gxShape aLineShape;
  2553.     gxShape aPointShape;
  2554.  
  2555.     static gxLine         lineGeometry = {ff(50), ff(50),
  2556.                                            ff(150), ff(150)};
  2557.  
  2558.     static gxPoint         newLastPointGeometry = {ff(300), ff(150)};
  2559.     aLineShape = GXNewLine(&lineGeometry);
  2560.     GXSetShapeFill(aLineShape, gxOpenFrameFill);
  2561.  
  2562.     aPointShape = GXNewPoint(&newLastPointGeometry);
  2563.     GXSetShapeParts(aLineShape, 2, 1, aPointShape, 
  2564.                          gxBreakNeitherEdit);
  2565.     GXDisposeShape(aPointShape);
  2566.     GXDrawShape(aLineShape);
  2567. }
  2568. The original line is shown in Figure 2-64.
  2569. Figure 2-64    A diagonal line
  2570.  
  2571. The line shape with the replaced last point is shown in Figure 2-65.
  2572. Figure 2-65    An edited line
  2573.  
  2574. For more information about editing shape parts and the GXSetShapeParts function, see the function description on page 2-131.
  2575.  
  2576.  
  2577. Applying Functions Described Elsewhere to Geometric Shapes
  2578.  
  2579. QuickDraw GX provides many functions that apply exclusively to geometric shapes. However, there are many other QuickDraw GX functions that apply to other types of shapes as well as geometric shapes. 
  2580. The next seven sections discuss how functions described elsewhere operate on geometric shapes. These sections are:
  2581. n    “Shape-Related Functions Applicable to Geometric Shapes” beginning on page 2-86
  2582. n    “Geometric Operations Applicable to Geometric Shapes” beginning on page 2-88
  2583. n    “Style-Related Functions Applicable to Geometric Shapes” beginning on page 2-89
  2584. n    “Ink-Related Functions Applicable to Geometric Shapes” beginning on page 2-89
  2585. n    “Transform-Related Functions Applicable to Geometric Shapes” beginning on page 2-89
  2586. Shape-Related Functions Applicable to Geometric Shapes
  2587.  
  2588. You can apply all of the functions described in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects to geometric shapes. These functions allow you to:
  2589. n    manipulate the shape object that represents the geometric shape (For example, you can copy, clone, cache, compare, and dispose of the bitmap shape.)
  2590. n    set the geometry, shape type, shape fill, and shape attributes of the geoemtric shape
  2591. n    change the style, ink, and transform objects that are associated with the geometric shape
  2592. n    manipulate the tags and owner count of the bitmap shape
  2593. Table 2-1 gives important information about geometric shapes for a subset of the functions from the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects. Functions described in that chapter that do not appear in this list exhibit the same behavior when applied to geometric shapes as they do when applied to other types of shapes.
  2594. Table 2-1    Shape-related functions that exhibit special behavior with geometric shapess
  2595. Function name    Action taken    
  2596. GXGetDefaultShape    Returns a reference to the default geometric shape of the specified type. See “The Geometric Shape Types” beginning on page 2-14 for information about the default geometric shapes.    
  2597. GXGetShapeFill    Returns the shape fill of the shape. See “Shape Fill” beginning on page 2-10 for a discussion of which shape fills are appropriate for which geometric shapes.    
  2598. GXGetShapeVector    Returns the geometry of a geometric shape as an untyped list of long values.    
  2599. GXNewShapeVector    Creates a geometric shape, initializing the geometric shape’s geometry from an untyped list of long values.    
  2600. GXSetDefaultShape    Allows you to specify the shape to copy when creating new geometric shapes. See “The Geometric Shape Types” beginning on page 2-14 for information about the default geometric shapes.    
  2601. GXSetShapeFill    Sets the shape fill of the shape. See “Shape Fill” beginning on page 2-10 for a discussion of which shape fills are appropriate for which geometric shapes.    
  2602. GXSetShapeType    Changes the shape type of the geoemtric shape and converts the shape fill and geometry as appropriate. See the rest of this section for more information about converting shape types.    
  2603. GXSetShapeVector    Replaces a geometric shape’s geometry with an untyped list of long values.    
  2604.  
  2605. When converting between geometric shape types, the behavior of the GXSetShapeType function depends on the new shape type. If the new shape type is gxPointType, gxLineType, or gxRectangleType, the new geometry is based on the bounds of the original geometry:
  2606. old type    new type    new geometry    
  2607. any    point    upper-left corner of bounds    
  2608. any    line    line from upper-left corner to lower-left corner    
  2609. any    rectangle    bounding rectangle of original geometry    
  2610.  
  2611. If the new shape type is gxCurveType, the conversion performed depends on the original shape type:
  2612. old type    new type    new geometry    
  2613. point    curve    new control points all set to original point    
  2614. line    curve    first and last points remain the same;
  2615. off-curve control point set equal to last point    
  2616. rectangle    curve    first point set to original upper-left point;
  2617. last point set to original lower-left point;
  2618. off-curve control point set equal to last point    
  2619. polygon    curve    new control points set to first three original control points    
  2620. path    curve    new control points set to first three original control points    
  2621.  
  2622. If the new shape type is gxPolygonType, this function retains all of the original geometric points:
  2623. old type    new type    new geometry    
  2624. point
  2625. line
  2626. rectangle    polygon
  2627.     single contour with same geometric points    
  2628. curve    polygon    single contour with same geometric points;
  2629. the off-curve point becomes on-curve    
  2630. path    polygon    same geometric points; all on-curve
  2631. (calculates approximation if curve error is not zero)    
  2632.  
  2633. When converting a path shape to a polygon shape, this function examines the curve error of the style of the path shape. If the curve error is not zero, this functions creates a polygon approximation of the original paths. For more information, see Chapter 3, “Geometric Styles,” in this book.
  2634. Finally, if the new shape type is gxPathType, this function retains all of the original geometry information:
  2635. old type    new type    new geometry    
  2636. point
  2637. line
  2638. curve
  2639. rectangle    path    single contour with same geometric points    
  2640. polygon    path    same number of contours; same geometric points;
  2641. all control points remain on-curve    
  2642.  
  2643. Geometric Operations Applicable to Geometric Shapes
  2644.  
  2645. You can apply any of the geometric operations described in Chapter 4, “Geometric Operations,” to the geometric shapes.
  2646. Style-Related Functions Applicable to Geometric Shapes
  2647.  
  2648. Geometric shapes make use of the geometric properties of their style objects. For this reason, you may apply shape-based functions (such as GXSetShapePen, GXSetShapeDash, and so on) described in Chapter 3, “Geometric Styles,” to geometric shapes. 
  2649. You may also apply any of the shape-based functions in the chapter “Typographic Styles” in Inside Macintosh: QuickDraw GX Typography to geometric shapes. However, these functions do not affect the way geometric shapes appear when drawn.
  2650. Ink-Related Functions Applicable to Geometric Shapes
  2651.  
  2652. You may apply any of the shape-based functions described in the chapter “Ink Objects” in  Inside Macintosh: QuickDraw GX Typography to geometric shapes. These functions include GXSetShapeColor, GXSetShapeTransfer, GXSetShapeInkAttributes, and so on.
  2653. Transform-Related Functions Applicable to Geometric Shapes
  2654.  
  2655. You may apply any of the shape-based functions described in the chapter “Transform Objects” in  Inside Macintosh: QuickDraw GX Typography to geometric shapes. These functions include GXSetShapeClip, GXSetShapeMapping, GXSetShapeHitTest, and so on.
  2656.  
  2657. Geometric Shapes Reference
  2658.  
  2659. QuickDraw GX provides four main types of shapes: geometric shapes, typographic shapes, bitmap shapes, and picture shapes. This section describes the data types and functions that are related to geometric shapes.
  2660. The “Data Types” section shows the structure definitions for the geometries of the geometric shapes.
  2661. The “Functions” section describes the functions that allow you to create and draw geometric shapes and functions that allow you to perform simple manipulations on shape geometries, such as replacing the entire geometry, or replacing certain points in a geometry.
  2662. Chapter 4, “Geometric Operations,” in this book describes functions that allow you to perform more advanced operations on shape geometries—operations such as insetting, intersecting, and so on.
  2663. Data Types
  2664.  
  2665. This section describes the structures that you use when creating and manipulating geometric shapes.
  2666. You use the gxPoint structure when creating a point shape and when specifying geometric point positions for all of the geometric shapes.
  2667. You use the gxLine structure when creating a line shape.
  2668. You use the gxCurve structure when creating a curve shape.
  2669. You use the gxRectangle structure when creating a rectangle shape and when specifying the bounding rectangle of a shape.
  2670. You use the gxPolygon structure when specifying a single contour made up of straight lines. You use the gxPolygons structure when specifying multiple contours made up of straight lines.
  2671. You use the gxPath structure when specifying a single contour made up of straight lines and curves. You use the gxPaths structure when specifying multiple path contours.
  2672. Point Structure
  2673.  
  2674. You use the gxPoint structure in a number of situations; for example, to specify the geometry of a point shape, to specify the position of geometric points in the geometries of other geometric shape types, to specify a location to hit-test, to specify the position of a bitmap, and so on.
  2675. The gxPoint structure is defined as follows:
  2676. struct gxPoint{
  2677.     fixed            x;
  2678.     fixed            y;
  2679. };
  2680. Field descriptions
  2681. x    A horizontal distance. Greater values of the x field indicate distances further to the right.
  2682. y    A vertical distance. Greater values of the y field indicate distances further down. 
  2683. Typically, QuickDraw GX interprets the values in the x and y fields as 1/72 inch units; for example, a value of 1 in the x and y fields typically means 1/72 inch to the right and down from the origin. The location of the origin depends on the context where you use the point; for example, it might be the upper-left corner of a view port.
  2684. Notice that the x and y fields are type fixed. QuickDraw GX allows you to specify fractional coordinate positions.
  2685. For more information about coordinates and coordinate spaces, see Inside Macintosh: QuickDraw GX Objects.
  2686. For more information about points and point shapes, see “Point Shapes” on page 2-15.
  2687. Line Structure
  2688.  
  2689. You use the gxLine structure to specify the geometry of a line shape.
  2690. The gxLine structure is defined as follows:
  2691. struct gxLine {
  2692.     struct gxPoint             first;
  2693.     struct gxPoint             last;
  2694. };
  2695. Field descriptions
  2696. first    The coordinate position where the line begins.
  2697. last    The coordinate position where the line ends. 
  2698. Notice that the endpoints of a line are ordered—lines have an implicit direction. This direction can affect how QuickDraw GX draws a line shape, particularly when the line shape has stylistic variations.
  2699. For more information about lines and line shapes, see “Line Shapes” on page 2-16.
  2700. Curves
  2701.  
  2702. You use the gxCurve structure to specify the geometry of a curve shape.
  2703. The gxCurve structure is defined as follows:
  2704. struct gxCurve {
  2705.     struct gxPoint             first;
  2706.     struct gxPoint             control;
  2707.     struct gxPoint             last;
  2708. };
  2709. Field descriptions
  2710. first    The coordinate position where the curve begins.
  2711. control    The coordinate position of the off-curve control point, which QuickDraw GX uses to determine the tangents of the curve. 
  2712. last    The coordinate position where the curve ends. 
  2713. The curve defined by these three points is a quadratic Bézier curve.
  2714. Because the geometric points that define a curve are ordered, curves have direction. The direction of a curve can affect how QuickDraw GX draws the curve shape, particularly when the curve shape has stylistic variations.
  2715. For more information about curves and curve shapes, see “Curve Shapes” on page 2-17.
  2716. Rectangle Structure
  2717.  
  2718. You use the gxRectangle structure in a variety of situations: to specify the geometry of a rectangle shape, to specify the bounding rectangle of another shape, and so on.
  2719. The gxRectangle structure is defined as:
  2720. struct gxRectangle {
  2721.     fixed            left;
  2722.     fixed            top;
  2723.     fixed            right;
  2724.     fixed            bottom;
  2725. };
  2726. Field descriptions
  2727. left    Specifies the x-coordinate of the rectangle’s first geometric point.
  2728. top    Specifies the y-coordinate of the rectangle’s first geometric point. 
  2729. right    Specifies the x-coordinate of the rectangle’s last geometric point. 
  2730. bottom    Specifies the y-coordinate of the rectangle’s last geometric point. 
  2731. You may specify a rectangle’s geometric points in any order—the coordinates in the left and top field do not have to correspond the rectangle’s upper-left corner. However, rectangles caclulated by QuickDrawz GX, such as those returned from geometric operations as described in Chapter 4, always have their coordinates specified in the standard order.
  2732. For more information about rectangles and rectangle shapes, see “Rectangle Shapes” on page 2-19.
  2733. Polygon Structures
  2734.  
  2735. You use the gxPolygon structure to specify a single polygon contour composed of straight lines.
  2736. The gxPolygon structure is defined as follows:
  2737. struct gxPolygon {
  2738.     long                    vectors;
  2739.     struct gxPoint                 vector[gxAnyNumber];
  2740. };
  2741. Field descriptions
  2742. vectors    The number of geometric points in the contour.
  2743. vector    The coordinates of the geometric points. 
  2744. The array index gxAnyNumber indicates that the gxPolygon data structure is a variable-length structure—it can include any number of points from 0 to 32767.
  2745. The gxPolygons structure allows you to group multiple polygon contours together. You use this structure when specifying the geometry of a polygon shape.
  2746. The gxPolygons structure is defined as follows:
  2747. struct gxPolygons{
  2748.     long                      contours;
  2749.     struct gxPolygon                 contour[gxAnyNumber];
  2750. };
  2751. Field descriptions
  2752. contours    Specifies the number of polygons.
  2753. contour    Contains the polygons. 
  2754. The array index gxAnyNumber indicates that the gxPolygons data structure is also a variable-length structure—it can include any number of gxPolygon structures from 0 to 32767.
  2755. For more information about polygons and polygon shapes, see “Polygon Shapes” on page 2-20.
  2756. Path Structures
  2757.  
  2758. You use the gxPath structure to specify a single contour composed of straight lines and curves.
  2759. The gxPath structure is defined as follows:
  2760. struct gxPath {
  2761.     long                    vectors;
  2762.     long                    controlBits[gxAnyNumber];
  2763.     struct gxPoint             vector[gxAnyNumber];
  2764. };
  2765. Field descriptions
  2766. vectors    The number of geometric points in the contour.
  2767. controlBits    Bit flags that indicate which geoemtric points are on curve and which are off-curve control points. 
  2768. vector    The coordinates of the geometric points. 
  2769. The array index gxAnyNumber indicates that the gxPolygon data structure is a variable-length structure—it can include any number of geometric points from 0 to 32767.
  2770. Each bit in the array specified in the controlBits field indicates whether a particular point in the array specified by the vector field is on curve or off curve. A value of 0 indicates that the corresponding point is on curve and a value of 1 incidates that the corresponding point is off curve.
  2771. The gxPaths structure allows you to group multiple path contours together. You use this data structure when specifying the geometry of a path shape.
  2772. The gxPaths structure is defined as follows:
  2773. struct gxPaths {
  2774.     long                   contours;
  2775.     struct gxPath             contour[gxAnyNumber];
  2776. };
  2777. Field descriptions
  2778. contours    The number of path contours.
  2779. contour    The path contours. 
  2780. The array index gxAnyNumber indicates that the gxPolygons data structure is also a variable-length structure—it can include any number of path contours from 0 to 32767.
  2781. For more information about paths and path shapes, see “Path Shapes” on page 2-23.
  2782. Functions
  2783.  
  2784. This section describes the functions available for
  2785. n    creating new geometric shapes
  2786. n    manipulating the geometries of geometric shapes
  2787. n    editing parts of shape geometries
  2788. n    drawing geometric shapes
  2789. Chapter 4, “Geometric Operations,” contains information about more sophisticateed functions for manipulating shape geometries.
  2790. For information about creating, drawing, and manipulating bitmap shapes, see Chapter 5, “Bitmap Shapes.”
  2791. For information about creating, drawing, and manipulating picture shapes, see Chapter 6, “Picture Shapes.”
  2792. For information about getting and setting the default geometric shapes and information about manipulating shape type and shape fill, see the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects. For information about hit-testing geometric shapes, see the chapter “Transform Objects” also in that book.
  2793. For information about creating, drawing, and manipulating typographic shapes, see Inside Macintosh: QuickDraw GX Typography.
  2794. Creating Geometric Shapes
  2795.  
  2796. QuickDraw GX provides a number of ways for you to create a new shape. The GXNewShape function allows you to create a shape by specifying only the shape type; the geometry of the new shape is set to its initial state—all geometric points are (0, 0) and polygons and paths have 0 contours. You can customize the shape’s geometry using the functions described in“Getting and Setting Shape Geometries” beginning on page 2-102.
  2797. The GXNewShape function is described in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  2798. QuickDraw GX also provides functions that allow you to specify a shape’s initial geometry when creating the shape. With the GXNewShapeVector function, you specify a shape type and an array of values. The function creates a new shape of the specified type and uses the array of values to initialize the new shape’s geometry.
  2799. The GXNewShapeVector function is also described in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  2800. The GXNewPoint, GXNewLine, GXNewCurve, GXNewRectangle, GXNewPolygons, and GXNewPaths functions all create a new shape of a specific type. These functions allow you to specify the shape’s initial geometry.
  2801. GXNewPoint  
  2802.  
  2803. You can use the GXNewPoint function to create a new point shape and initialize its geometry.
  2804. gxShape GXNewPoint(const gxPoint *data);
  2805. data    A pointer to the initial point geometry.
  2806. DESCRIPTION
  2807. The GXNewPoint function creates a copy of the default point shape, sets the owner count of the copy to 1, initializes its geometry with the values in the data parameter, and returns a reference to it as the function result.
  2808. Although this function creates a copy of the default point shape, it does not create a copy of the default point’s style, ink, or transform objects. The new point shape returned by this function contains references to same style, ink, and transform as the default point shape. 
  2809. SPECIAL CONSIDERATIONS
  2810. If no error results, the GXNewPoint function creates a shape; you are responsible for disposing of this shape when you no longer need it. See Inside Macintosh: QuickDraw GX Objects for information about creating and disposing of shapes.
  2811. ERRORS, WARNINGS, AND NOTICES
  2812. Errors    
  2813. out_of_memory    
  2814. parameter_is_nil    
  2815.  
  2816. SEE ALSO
  2817. For an example that uses this function, see “Creating and Drawing Points” beginning on page 2-27.
  2818. For a discussion of points and the default point shape, see “Point Shapes” on page 2-15.
  2819. For a description of the gxPoint structure, see “Point Structure” on page 2-90.
  2820. To create a new point shape without specifying an initial geometry, see the description of the GXNewShape function in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  2821. To set the geometry of an existing point shape, see the description of the GXSetPoint function on page 2-103.
  2822. To draw a point geometry, see the description of GXDrawPoint on page 2-134. To draw a point shape, see the description of GXDrawShape in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  2823. GXNewLine  
  2824.  
  2825. You can use the GXNewLine function to create a new line shape and initialize its geometry.
  2826. gxShape GXNewLine(const gxLine *data);
  2827. data    A pointer to the initial line geometry.
  2828. DESCRIPTION
  2829. The GXNewLine function creates a copy of the default line shape, sets the owner count of the copy to 1, initializes its geometry with the values in the data parameter, and returns a reference to it as the function result.
  2830. Although this function creates a copy of the default line shape, it does not create a copy of the default line’s style, ink, or transform objects. The new line shape returned by this function contains references to same style, ink, and transform as the default line shape. 
  2831. SPECIAL CONSIDERATIONS
  2832. If no error results, the GXNewLine function creates a shape; you are responsible for disposing of this shape when you no longer need it. See Inside Macintosh: QuickDraw GX Objects for information about creating and disposing of shapes.
  2833. ERRORS, WARNINGS, AND NOTICES
  2834. Errors    
  2835. out_of_memory    
  2836. parameter_is_nil    
  2837.  
  2838. SEE ALSO
  2839. For an example that usesthis function, see “Creating and Drawing Lines” beginning on page 2-32.
  2840. For a discussion of lines and the default line shape, see “Line Shapes” on page 2-16.
  2841. For a description of the gxLine structure, see page 2-91.
  2842. To create a new line shape without specifying an initial geometry, see the description of the GXNewShape function in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  2843. To set the geometry of an existing line shape, see the description of the GXSetLine function on page 2-105.
  2844. To draw a line geometry without creating a line shape, see the description of GXDrawLine on page 2-135. To draw a line shape, see the description of GXDrawShape in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  2845. GXNewCurve  
  2846.  
  2847. You can use the GXNewCurve function to create a new curve shape and initialize its geometry.
  2848. gxShape GXNewCurve(const gxCurve *data);
  2849. data    A pointer to the initial curve geometry.
  2850. DESCRIPTION
  2851. The GXNewCurve function creates a copy of the default curve shape, sets the owner count of the copy to 1, initializes its geometry with the values in the data parameter, and returns a reference to it as the function result.
  2852. Although this function creates a copy of the default curve shape, it does not create a copy of the default curve’s style, ink, or transform objects. The new curve shape returned by this function contains references to same style, ink, and transform as the default curve shape. 
  2853. SPECIAL CONSIDERATIONS
  2854. If no error results, the GXNewCurve function creates a shape; you are responsible for disposing of this shape when you no longer need it. See Inside Macintosh: QuickDraw GX Objects for information about creating and disposing of shapes.
  2855. ERRORS, WARNINGS, AND NOTICES
  2856. Errors    
  2857. out_of_memory    
  2858. parameter_is_nil    
  2859.  
  2860. SEE ALSO
  2861. For an example that uses this function, see “Creating and Drawing Curves” beginning on page 2-39.
  2862. For a discussion of curves and the default curve shape, see “Curve Shapes” beginning on page 2-17.
  2863. For a description of the gxCurve structure, see page 2-91.
  2864. To create a new curve shape without specifying an initial geometry, see the description of the GXNewShape function in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  2865. To set the geometry of an existing curve shape, see the description of the GXSetCurve function on page 2-107.
  2866. To draw a curve geometry without creating a curve shape, see the description of GXDrawCurve on page 2-135. To draw a curve shape, see the description of GXDrawShape in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  2867. GXNewRectangle  
  2868.  
  2869. You can use the GXNewRectangle function to create a new rectangle shape and initialize its geometry.
  2870. gxShape GXNewRectangle(const gxRectangle *data);
  2871. data    A pointer to the initial rectangle geometry.
  2872. DESCRIPTION
  2873. The GXNewRectangle function creates a copy of the default rectangle shape, sets the owner count of the copy to 1, initializes its geometry with the values in the data parameter, and returns a reference to it as the function result.
  2874. Although this function creates a copy of the default rectangle shape, it does not create a copy of the default rectangle’s style, ink, or transform objects. The new rectangle shape returned by this function contains references to same style, ink, and transform as the default rectangle shape. 
  2875. SPECIAL CONSIDERATIONS
  2876. If no error results, the GXNewRectangle function creates a shape; you are responsible for disposing this shape when you no longer need it. See Inside Macintosh: QuickDraw GX Objects for information about creating and disposing of shapes.
  2877. ERRORS, WARNINGS, AND NOTICES
  2878. Errors    
  2879. out_of_memory    
  2880. parameter_is_nil    
  2881.  
  2882. SEE ALSO
  2883. For an example that uses this function, see “Creating and Drawing Rectangles” beginning on page 2-36.
  2884. For a discussion of rectangles and the default rectangle shape, see “Rectangle Shapes” beginning on page 2-19.
  2885. For a description of the gxRectangle structure, see page 2-91.
  2886. To create a new rectangle shape without specifying an initial geometry, see the description of the GXNewShape function in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  2887. To set the geometry of an existing rectangle shape, see the description of the GXSetRectangle function on page 2-109.
  2888. To draw a rectangle geometry without creating a rectangle shape, see the description of GXDrawRectangle on page 2-136. To draw a rectangle shape, see the description of GXDrawShape in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  2889. GXNewPolygons  
  2890.  
  2891. You can use the GXNewPolygons function to create a new polygon shape and initialize its geometry.
  2892. gxShape GXNewPolygons(const gxPolygons *data);
  2893. data    A pointer to the initial polygon geometry.
  2894. DESCRIPTION
  2895. The GXNewPolygons function creates a copy of the default polygon shape, sets the owner count of the copy to 1, initializes its geometry with the values in the data parameter, and returns a reference to it as the function result.
  2896. Although this function creates a copy of the default polygon shape, it does not create a copy of the default polygon’s style, ink, or transform objects. The new polygons shape returned by this function contains references to same style, ink, and transform as the default polygon shape. 
  2897. SPECIAL CONSIDERATIONS
  2898. If no error results, the GXNewPolygons function creates a shape; you are responsible for disposing of this shape when you no longer need it. See Inside Macintosh: QuickDraw GX Objects for information about creating and disposing of shapes.
  2899. ERRORS, WARNINGS, AND NOTICES
  2900. Errors    
  2901. out_of_memory    
  2902. parameter_is_nil    
  2903. number_of_contours_exceeds_implementation_limit    
  2904. size_of_polygon_exceeds_implementation_limit    
  2905.  
  2906. SEE ALSO
  2907. For an example that uses this function, see “Creating and Drawing Polygons” beginning on page 2-40.
  2908. For a discussion of polygons and the default polygon shape, see “Polygon Shapes” beginning on page 2-20.
  2909. For a description of the gxPolygon structure, see page 2-92.
  2910. To create a new polygon shape without specifying an initial geometry, see the description of the GXNewShape function in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  2911. To set the geometry of an existing polygon shape, see the description of the GXSetPolygons function on page 2-111.
  2912. To draw a polygon geometry without creating a polygon shape, see the description of GXDrawPolygons on page 2-137. 
  2913. To draw a polygon shape, see the description of GXDrawShape in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  2914. GXNewPaths  
  2915.  
  2916. You can use the GXNewPaths function to create a new path shape and initialize its geometry.
  2917. gxShape GXNewPaths(const gxPaths *data);
  2918. data    A pointer to the initial path geometry.
  2919. DESCRIPTION
  2920. The GXNewPaths function creates a copy of the default path shape, sets the owner count of the copy to 1, initializes its geometry with the values in the data parameter, and returns a reference to it as the function result.
  2921. Although this function creates a copy of the default paths shape, it does not create a copy of the default paths shape’s style, ink, or transform objects. The new paths shape returned by this function contains references to same style, ink, and transform as the default paths shape. 
  2922. SPECIAL CONSIDERATIONS
  2923. If no error results, the GXNewPaths function creates a shape; you are responsible for disposing of this shape when you no longer need it. See Inside Macintosh: QuickDraw GX Objects for information about creating and disposing of shapes.
  2924. ERRORS, WARNINGS, AND NOTICES
  2925. Errors    
  2926. out_of_memory    
  2927. parameter_is_nil    
  2928. number_of_contours_exceeds_implementation_limit    
  2929. size_of_path_exceeds_implementation_limit    
  2930.  
  2931. SEE ALSO
  2932. For an example that uses this function, see “Creating and Drawing Paths” beginning on page 2-49.
  2933. For a discussion of paths and the default path shape, see “Path Shapes” beginning on page 2-23.
  2934. For a description of the gxPaths structure, see page 2-93.
  2935. To create a new path shape without specifying an initial geometry, see the description of the GXNewShape function in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  2936. To set the geometry of an existing paths shape, see the description of the GXSetPaths function on page 2-114.
  2937. To draw a path geometry without creating a path shape, see the description of GXDrawPaths on page 2-138. To draw a path shape, see the description of GXDrawShape in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  2938. Getting and Setting Shape Geometries
  2939.  
  2940. The geometry property of geometric shapes contains the geometric points that define the shape. The geometries of polygon shapes and path shapes also contain some additional information, such as the number of separate contours, how many geometric points in each contour, and (for paths) which geometric points are on curve and which are off-curve control points.
  2941. For general information about each type of geometry, see “About Geometric Shapes” beginning on page 2-5. For specific definitions of each type of geometric structure, see the section “Data Types” beginning on page 2-90.
  2942. The GXSetShapeVector function allows you to change the geometry of any shape. With this function, you specify a shape and an array of values. The function replaces the geometry of the specified shape with the values in the array. This function works for other shape types as well as geometric shapes. You can find more information about it in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  2943. The GXGetPoint, GXGetLine, GXGetCurve, GXGetRectangle, GXGetPolygons, and GXGetPaths functions each return the geometry of a specific type of shape.
  2944. The GXSetPoint, GXSetLine, GXSetCurve, GXSetRectangle, GXSetPolygons, and GXSetPaths functions each replace the geometry of a specific type of shape.
  2945. GXGetPoint  
  2946.  
  2947. You can use the GXGetPoint function to determine the geometry of an existing point shape.
  2948. gxPoint *GXGetPoint(gxShape source, gxPoint *data);
  2949. source    A reference to the point shape whose geometry you want to determine.
  2950. data    A pointer to a gxPoint structure. The function copies the source shape’s geometry into this structure.
  2951. DESCRIPTION
  2952. The GXGetPoint function copies the geometry information from the source point shape into the gxPoint structure pointed to by the data parameter. As a convenience, this function also returns a pointer to the point geometry as the function result.
  2953. If the source shape is not a point shape, this function posts the error code illegal_type_for_shape. 
  2954. You must pass a pointer to a gxPoint structure in the data parameter—if you pass nil for this parameter, the function posts the error code parameter_is_nil.
  2955. ERRORS, WARNINGS, AND NOTICES
  2956. Errors    
  2957. out_of_memory    
  2958. shape_is_nil    
  2959. illegal_type_for_shape    
  2960. parameter_is_nil    
  2961.  
  2962. SEE ALSO
  2963. For general information about point geometries, see “Point Shapes” on page 2-15. 
  2964. For the definition of the gxPoint structure, see page 2-90.
  2965. To create a new point shape, use the GXNewPoint function, which is described on page 2-95.
  2966. To change the geometry of an existing point shape, use the GXSetPoint function, which is described in the next section.
  2967. To draw a point geometry without creating a point shape, use the GXDrawPoint function, which is described on page 2-134. To draw a point shape, use the GXDrawShape function, which is described in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  2968. GXSetPoint  
  2969.  
  2970. You can use the GXSetPoint function to change the geometry of an existing point shape.
  2971. void GXSetPoint(gxShape target, const gxPoint *data);
  2972. target    A reference to the point shape whose geometry you want to change.
  2973. data    A pointer to the new point geometry.
  2974. DESCRIPTION
  2975. The GXSetPoint function copies the geometry information from the data parameter into the geometry property of the target point shape.
  2976. If the target shape is not a point shape, this function posts the error code illegal_type_for_shape. You must provide a pointer to a gxPoint structure in the data parameter—if you pass nil for the data parameter, the function posts the error code parameter_is_nil.
  2977. ERRORS, WARNINGS, AND NOTICES
  2978. Errors    
  2979. out_of_memory    
  2980. shape_is_nil    
  2981. parameter_is_nil    
  2982. illegal_type_for_shape    
  2983. Warnings    
  2984. shape_access_not_allowed    
  2985.  
  2986. SEE ALSO
  2987. For general information about point geometries, see “Point Shapes” on page 2-15. 
  2988. For the definition of the gxPoint structure, see page 2-90.
  2989. To create a new point shape, use the GXNewPoint function, which is described on page 2-95.
  2990. To examine the geometry of an existing point shape, use the GXGetPoint function, which is described on page 2-102.
  2991. To draw a point geometry without creating a point shape, use the GXDrawPoint function, which is described on page 2-134. To draw a point shape, use the GXDrawShape function, which is described in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  2992. GXGetLine  
  2993.  
  2994. You can use the GXGetLine function to determine the geometry of an existing line shape.
  2995. gxLine *GXGetLine(gxShape source, gxLine *data);
  2996. source    A reference to the line shape whose geometry you want to determine.
  2997. data    A pointer to a gxLine structure. The function copies the source shape’s geometry into this structure.
  2998. DESCRIPTION
  2999. The GXGetLine function copies the geometry information from the source line shape into the gxLine structure pointed to by the data parameter. As a convenience, this function also returns a pointer to the line geometry as the function result.
  3000. If the source shape is not a point shape, this function posts the error code illegal_type_for_shape. 
  3001. You must pass a pointer to a gxLine structure inthe data parameter—if you pass nil for this parameter, the function posts the error code parameter_is_nil.
  3002. ERRORS, WARNINGS, AND NOTICES
  3003. Errors    
  3004. out_of_memory    
  3005. shape_is_nil    
  3006. illegal_type_for_shape    
  3007. parameter_is_nil    
  3008.  
  3009. SEE ALSO
  3010. For general information about line geometries, see “Line Shapes” on page 2-16. 
  3011. For the definition of the gxLine structure, see page 2-91.
  3012. To create a new line shape, use the GXNewLine function, which is described on page 2-96.
  3013. To change the geometry of an existing line shape, use the GXSetLine function, which is described in the next section.
  3014. To draw a line geometry without creating a line shape, use the GXDrawLine function, which is described on page 2-135. To draw a line shape, use the GXDrawShape function, which is described in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  3015. GXSetLine   
  3016.  
  3017. You can use the GXSetLine function to change the geometry of a line shape.
  3018. void GXSetLine(gxShape target, const gxLine *data);
  3019. target    A reference to the line shape whose geometry you want to change.
  3020. data    A pointer to the new line geometry.
  3021. DESCRIPTION
  3022. The GXSetLine function copies the geometry information from the data parameter into the geometry property of the target line shape. If the target shape is not a line shape, this function posts the error code illegal_type_for_shape. 
  3023. You must provide a pointer to a gxLine structure in the data parameter—if you pass nil for this parameter, the function posts the error code parameter_is_nil.
  3024. ERRORS, WARNINGS, AND NOTICES
  3025. Errors    
  3026. out_of_memory    
  3027. shape_is_nil    
  3028. parameter_is_nil    
  3029. illegal_type_for_shape    
  3030. Warnings    
  3031. shape_access_not_allowed    
  3032.  
  3033. SEE ALSO
  3034. For general information about line geometries, see “Line Shapes” on page 2-16. 
  3035. For the definition of the gxLine structure, see page 2-91.
  3036. To create a new line shape, use the GXNewLine function, which is described on page 2-96.
  3037. To examine the geometry of an existing line shape, use the GXGetLine function, which is described on page 2-104.
  3038. To draw a line geometry without creating a line shape, use the GXDrawLine function, which is described on page 2-135. To draw a line shape, use the GXDrawShape function, which is described in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  3039. GXGetCurve  
  3040.  
  3041. You can use the GXGetCurve function to determine the geometry of an existing curve shape.
  3042. gxCurve *GXGetCurve(gxShape source, gxCurve *data);
  3043. source    A reference to the curve shape whose geometry you want to determine.
  3044. data    A pointer to a gxCurve structure. The function copies the source shape’s geometry into this structure.
  3045. DESCRIPTION
  3046. The GXGetCurve function copies the geometry information from the source curve shape into the gxCurve structure pointed to by the data parameter. As a convenience, this function also returns a pointer to the curve geometry as the function result.
  3047. If the source shape is not a curve shape, this function posts the error code illegal_type_for_shape. 
  3048. You must pass a pointer to a gxCurve structure in the data parameter—if you pass nil for this parameter, the function posts the error code parameter_is_nil.
  3049. ERRORS, WARNINGS, AND NOTICES
  3050. Errors    
  3051. out_of_memory    
  3052. shape_is_nil    
  3053. illegal_type_for_shape    
  3054. parameter_is_nil    
  3055.  
  3056. SEE ALSO
  3057. For general information about curve geometries, see “Curve Shapes” on page 2-17. 
  3058. For the definition of the gxCurve structure, see page 2-91.
  3059. To create a new curve shape, use the GXNewCurve function, which is described on page 2-97.
  3060. To change the geometry of an existing curve shape, use the GXSetCurve function, which is described in the next section.
  3061. To draw a curve geometry without creating a curve shape object, use the GXDrawCurve function, which is described on page 2-135. To draw a curve shape, use the GXDrawShape function, which is described in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  3062. GXSetCurve  
  3063.  
  3064. You can use the GXSetCurve function to change the geometry of a curve shape.
  3065. void GXSetCurve(gxShape target, const gxCurve *data);
  3066. target    A reference to the curve shape whose geometry you want to change.
  3067. data    A pointer to the new curve geometry.
  3068. DESCRIPTION
  3069. The GXSetCurve function copies the geometry information from the data parameter into the geometry property of the target line shape. If the target shape is not a curve shape, this function posts the error code illegal_type_for_shape. 
  3070. You must provide a pointer to a gxCurve structure in the data parameter—if you pass nil for this parameter, the function posts the error code parameter_is_nil.
  3071. ERRORS, WARNINGS, AND NOTICES
  3072. Errors    
  3073. out_of_memory    
  3074. shape_is_nil    
  3075. parameter_is_nil    
  3076. illegal_type_for_shape    
  3077. Warnings    
  3078. shape_access_not_allowed    
  3079.  
  3080. SEE ALSO
  3081. For general information about curve geometries, see “Curve Shapes” on page 2-17. 
  3082. For the definition of the gxCurve structure, see page 2-91.
  3083. To create a new curve shape, use the GXNewCurve function, which is described on page 2-97.
  3084. To examine the geometry of an existing curve shape, use the GXGetCurve function, which is described on page 2-106.
  3085. To draw a curve geometry without creating a curve shape, use the GXDrawCurve function, which is described on page 2-135. To draw a curve shape, use the GXDrawShape function, which is described in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  3086. GXGetRectangle  
  3087.  
  3088. You can use the GXGetRectangle function to determine the geometry of an existing rectangle shape.
  3089. gxRectangle *GXGetRectangle(gxShape source, gxRectangle *data);
  3090. source    A reference to the rectangle shape whose geometry you want to determine.
  3091. data    A pointer to a gxRectangle structure. The function copies the source shape’s geometry into this structure.
  3092. DESCRIPTION
  3093. The GXGetRectangle function copies the geometry information from the source rectangle shape into the gxRectangle data structure pointed to by the data parameter. As a convenience, this function also returns a pointer to the rectangle geometry as the function result.
  3094. If the source shape is not a rectangle shape, this function posts the error code illegal_type_for_shape. 
  3095. You must pass a pointer to a gxRectangle structure in the data parameter—if you pass nil for this parameter, the function posts the error code parameter_is_nil.
  3096. ERRORS, WARNINGS, AND NOTICES
  3097. Errors    
  3098. out_of_memory    
  3099. shape_is_nil    
  3100. illegal_type_for_shape    
  3101. parameter_is_nil    
  3102.  
  3103. SEE ALSO
  3104. For general information about rectangle geometries, see “Rectangle Shapes” on page 2-19. 
  3105. For the definition of the gxRectangle structure, see page 2-91.
  3106. To create a new rectangle shape, use the GXNewRectangle function, which is described on page 2-98.
  3107. To determine the bounding rectangle of a shape, use the GXGetShapeBounds function, which is described in the Chapter 4, “Geometric Operations,” in this book.
  3108. To change the geometry of an existing rectangle shape, use the GXSetRectangle function, which is described in the next section.
  3109. To draw a rectangle geometry without creating a rectangle shape, use the GXDrawRectangle function, which is described on page 2-136. To draw a rectangle shape, use the GXDrawShape function, which is described in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  3110. GXSetRectangle  
  3111.  
  3112. You can use the GXSetRectangle function to change the geometry of a rectangle shape.
  3113. void GXSetRectangle(gxShape target, const gxRectangle *data);
  3114. target    A reference to the rectangle shape whose geometry you want to change.
  3115. data    A pointer to the new rectangle geometry.
  3116. DESCRIPTION
  3117. The GXSetRectangle function copies the geometry information from the data parameter into the geometry property of the target line shape. If the target shape is not a rectangle shape, this function posts the error code illegal_type_for_shape. 
  3118. You must provide a pointer to a gxRectangle structure in the data parameter—if you pass nil for this parameter, the function posts the error code parameter_is_nil.
  3119. ERRORS, WARNINGS, AND NOTICES
  3120. Errors    
  3121. out_of_memory    
  3122. shape_is_nil    
  3123. parameter_is_nil    
  3124. illegal_type_for_shape    
  3125. Warnings    
  3126. shape_access_not_allowed    
  3127.  
  3128. SEE ALSO
  3129. For general information about rectangle geometries, see “Rectangle Shapes” on page 2-19. 
  3130. For the definition of the gxRectangle structure, see page 2-91.
  3131. To create a new rectangle shape, use the GXNewRectangle function, which is described on page 2-98.
  3132. To examine the geometry of an existing rectangle shape, use the GXGetRectangle function, which is described on page 2-108.
  3133. To draw a rectangle geometry without creating a rectangle shape, use the GXDrawRectangle function, which is described on page 2-136. To draw a rectangle shape, use the GXDrawShape function, which is described in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  3134. GXGetPolygons  
  3135.  
  3136. You can use the GXGetPolygons function to determine the geometry of a polygon shape.
  3137. long GXGetPolygons(gxShape source, gxPolygons *data);
  3138. source    A reference to the polygon shape whose geometry you want to determine.
  3139. data    A pointer to a gxPolygons data structure. The function copies the source shape’s geometry into this structure.
  3140. DESCRIPTION
  3141. The GXGetPolygons function copies the geometry information from the source polygon shape into the gxPolygons structure pointed to by the data parameter. As the function result, this function returns the length in bytes of the polygon geometry.
  3142. If the source shape is not a polygons shape, this function posts the error code illegal_type_for_shape.
  3143. You may pass nil for the data parameter. In this case, the GXGetPolygons function still returns the length of the data as the function result, but it does not return the actual data in data parameter.
  3144. Typically, to use this function, you go through the following steps:
  3145.     1.    Determine the length of the polygon data by calling this function, passing nil for the data parameter.
  3146.     2.    Allocate enough memory to hold the polygon data.
  3147.     3.    Call this function again, passing a pointer to the allocated memory in the data parameter.
  3148. ERRORS, WARNINGS, AND NOTICES
  3149. Errors    
  3150. out_of_memory    
  3151. shape_is_nil    
  3152. illegal_type_for_shape    
  3153. parameter_is_nil    
  3154.  
  3155. SEE ALSO
  3156. For general information about polygon geometries, see “Polygon Shapes” on page 2-20. 
  3157. For the definition of the gxPolygons structure, see page 2-92.
  3158. To create a new polygons shape, use the GXNewPolygons function, which is described on page 2-99.
  3159. To change the geometry of an existing polygon shape, use the GXSetPolygons function, which is described in the next section.
  3160. To draw a polygon geometry without creating a polygon shape, use the GXDrawPolygons function, which is described on page 2-137. To draw a polygons shape, use the GXDrawShape function, which is described in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  3161. GXSetPolygons  
  3162.  
  3163. You can use the GXSetPolygons function to change the geometry of a polygon shape.
  3164. void GXSetPolygons(gxShape target, const gxPolygons *data);
  3165. target    A reference to the polygon shape whose geometry you want to change.
  3166. data    A pointer to new polygon geometry.
  3167. DESCRIPTION
  3168. The GXSetPolygons function copies the geometry information from the data parameter into the geometry property of the target polygon shape. If the target shape is not a polygons shape, this function posts the error code illegal_type_for_shape. 
  3169. You must provide a pointer to a gxPolygons structure in the data parameter—if you pass nil for this parameter, the function posts the error code parameter_is_nil.
  3170. ERRORS, WARNINGS, AND NOTICES
  3171. Errors    
  3172. out_of_memory    
  3173. shape_is_nil    
  3174. parameter_is_nil    
  3175. illegal_type_for_shape    
  3176. number_of_contours_exceeds_implementation_limit    
  3177. size_of_polygon_exceeds_implementation_limit    
  3178. Warnings    
  3179. shape_access_not_allowed    
  3180.  
  3181. SEE ALSO
  3182. For general information about polygon geometries, see “Polygon Shapes” on page 2-20. 
  3183. For the definition of the gxPolygons structure, see page 2-92.
  3184. To create a new polygon shape, use the GXNewPolygons function, which is described on page 2-99.
  3185. To examine the geometry of an existing polygon shape, use the GXGetPolygons function, which is described on page 2-110.
  3186. To draw a polygon geometry without creating a polygon shape, use the GXDrawPolygons function, which is described on page 2-137. To draw a polygon shape, use the GXDrawShape function, which is described in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  3187. GXGetPaths  
  3188.  
  3189. You can use the GXGetPaths function to determine the geometry of a path shape.
  3190. long GXGetPaths(gxShape source, gxPaths *data);
  3191. source    A reference to the path shape whose geometry you want to determine.
  3192. data    A pointer to a gxPaths structure. The function copies the source shape’s geometry into this structure.
  3193. DESCRIPTION
  3194. The GXGetPaths function copies the geometry information from the source path shape into the gxPaths structure pointed to by the data parameter. As the function result, this function returns the length in bytes of the path geometry.
  3195. If the source shape is not a path shape, this function posts the error code illegal_type_for_shape.
  3196. You may pass nil for the data parameter. In this case, the GXGetPaths function still returns the length of the data, but it does not return the actual data in the data parameter.
  3197. Typically, to use this function, you go through the following steps:
  3198.     1.    Determine the length of the path data by calling this function, passing nil for the data parameter.
  3199.     2.    Allocate enough memory to hold the path data.
  3200.     3.    Call this function again, passing a pointer to the allocated memory in the data parameter.
  3201. ERRORS, WARNINGS, AND NOTICES
  3202. Errors    
  3203. out_of_memory    
  3204. shape_is_nil    
  3205. illegal_type_for_shape    
  3206. parameter_is_nil    
  3207.  
  3208. SEE ALSO
  3209. For general information about path geometries, see “Path Shapes” on page 2-23. 
  3210. For the definition of the gxPaths structure, see page 2-93.
  3211. To create a new path shape, use the GXNewPaths function, which is described on page 2-101.
  3212. To change the geometry of an existing path shape, use the GXSetPaths function, which is described in the next section.
  3213. To draw a path geometry without creating a path shape, use the GXDrawPaths function, which is described on page 2-138. To draw a path shape, use the GXDrawShape function, which is described in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  3214. GXSetPaths  
  3215.  
  3216. You can use the GXSetPathsfunction to change the geometry of a path shape.
  3217. void GXSetPaths(gxShape target, const gxPaths *data);
  3218. target    A reference to the path shape whose geometry you want to change.
  3219. data    A pointer to new path geometry.
  3220. DESCRIPTION
  3221. The GXSetPaths function copies the geometry information from the data parameter into the geometry property of the target path shape. If the target shape is not a path shape, this function posts the error code illegal_type_for_shape. 
  3222. You must provide a pointer to a gxPaths structure in the data parameter—if you pass nil for this parameter, the function posts the error code parameter_is_nil.
  3223. ERRORS, WARNINGS, AND NOTICES
  3224. Errors    
  3225. out_of_memory    
  3226. shape_is_nil    
  3227. parameter_is_nil    
  3228. illegal_type_for_shape    
  3229. number_of_contours_exceeds_implementation_limit    
  3230. size_of_polygon_exceeds_implementation_limit    
  3231. Warnings    
  3232. shape_access_not_allowed    
  3233.  
  3234. SEE ALSO
  3235. For general information about path geometries, see “Path Shapes” on page 2-23. 
  3236. For the definition of the gxPaths structure, see page 2-93.
  3237. To create a new path shape, use the GXNewPaths function, which is described on page 2-101.
  3238. To examine the geometry of an existing path shape, use the GXGetPaths function, which is described on page 2-112.
  3239. To draw a path geometry without creating a path shape, use the GXDrawPaths function, which is described on page 2-138. To draw a path shape, use the GXDrawShape function, which is described in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  3240. Editing Shape Geometries
  3241.  
  3242. The functions described in the previous section, “Getting and Setting Shape Geometries,” allow you to examine and replace entire shape geometries. The functions in this section provide more sophisticated abilities—with these functions, you can examine and edit specific parts of geometries.
  3243. For example, the GXCountShapeContours function allows you to determine the number of contours in a shape’s geometry. For polygon and path shapes, this number is an integral part of the geometry—it is the first value stored in the geometry; for other geometric shapes, this function simply returns 1.
  3244. Similarly, the GXCountShapePoints function returns the number of geometric points in a specified contour of a shape’s geometry.
  3245. The GXGetShapeIndex function returns the geometric index of a specific geometric point given a contour number and the index of the geometric point within the contour. (Remember, each geometric point in a geometry has an geometric index—if you consider a geometry as a list of geometric points starting from the first geometric point of the first contour to the last geometric point of the last contour, the geometric index of a particular geometric point is its position in this list.) You use geometric indexes to specify ranges of geometric points in many of the functions in this section.
  3246. You can use the GXGetShapePoints function to obtain a copy of a particular range of geometric points from a shape’s geometry, and you can use the GXSetShapePoints to replace a particular range of geometric points in a shape’s geometry.
  3247. You can use the GXGetPolygonParts function to extract a range of geometric points from an existing polygon shape and put them into a new polygon geometry. You can use the GXSetPolygonParts function to replace any range of geometric points in an existing polygon shape with any new polygon geometry.
  3248. Similarly, you can use the GetPathsParts function to extract a range of geometric points from an existing path shape and put them into a new path geometry, and you can use the SetPathsParts function to replace any range of geometric points in an existing path shape with any new path geometry.
  3249. The GXGetShapeParts and GXSetShapeParts functions allow the broadest editing control. With the GXGetShapeParts function, you can extract any range of geometric points from an existing shape and put them into a new shape. With the GXSetShapeParts function, you can replace any range of geometric points in an existing shape with the entire geometry of another shape. 
  3250. You can apply GXCountShapeContours, GXCountShapePoints, GXGetShapeIndex, GXGetShapePoints, GXSetShapePoints, GXGetShapeParts, and GXSetShapeParts functions to other shape types as well as geometric shapes. Information about how they work for geometric shapes is presented in this section. You can find more information about these functinos in Chapter 5, “Bitmaps,” and Chapter 6, “Pictures,” and in Inside Macintosh: QuickDraw GX Typography.
  3251. GXCountShapeContours  
  3252.  
  3253. You can use the GXCountShapeContours function to determine the number of contours in a shape.
  3254. long GXCountShapeContours(gxShape source);
  3255. source    A reference to the shape whose contours you want to count.
  3256. function result    The number of contours in the source shape.
  3257. DESCRIPTION
  3258. The GXCountShapeContours function returns as its function result the number of contours in in the source shape. For polygon and path shapes, this number is the the first value in the geometry, which indicates the total number of polygon contours or path contours contained in the shape. For the other geometric shapes—points, lines, curves, and rectangles—this function returns the value 1.
  3259. ERRORS, WARNINGS, AND NOTICES
  3260. Errors    
  3261. out_of_memory    
  3262. shape_is_nil    
  3263.  
  3264. SEE ALSO
  3265. For a discussion of contours, see “Shape Geometry” on page 2-8, “Polygon Shapes” on page 2-20, and “Path Shapes” on page 2-23.
  3266. To learn how this function works for typographic shape types, see Inside Macintosh: QuickDraw GX Typography.
  3267. To determine the number of points in a specific contour of a shape, use the GXCountShapePoints function, which is described in the next section.
  3268. GXCountShapePoints  
  3269.  
  3270. You can use the GXCountShapePoints function to determine the number of geometric points in a specific contour of a shape.
  3271. long GXCountShapePoints(gxShape source, long contour);
  3272. source    A reference to the shape containing the contour.
  3273. contour    The index of the contour whose geometric points you want to count.
  3274. function result    The number of points in the specified contour of the source shape.
  3275. DESCRIPTION
  3276. The GXCountShapePoints function returns as its function result the number of points in contour specified by the contour parameter of the shape specified by the source parameter. If you pass 0 for the contour parameter, this function returns the total number of geometric points in the shape.
  3277. For the geometric shapes with only one contour—points, lines, curves, and rectangles— you must pass a 0 or a 1 in the contour parameter. For polygons and paths shapes, the value you provide for the contour parameter must be 0 or greater and must be equal to or less than the actual number of contours in the shape. Otherwise, the function posts a contour_out_of_range warning.
  3278. ERRORS, WARNINGS, AND NOTICES
  3279. Errors    
  3280. out_of_memory    
  3281. shape_is_nil    
  3282. Warnings    
  3283. graphic_type_does_not_contain_points    
  3284. contour_out_of_range    
  3285.  
  3286. SEE ALSO
  3287. For a discussion of geometric points, see the section “About Geometric Shapes” beginning on page 2-5.
  3288. To learn how this function works for typographic shape types, see Inside Macintosh: QuickDraw GX Typography.
  3289. To learn how this function works for bitmap and picture shape types, see Chapter 5, “Bitmaps,” and Chapter 6, “Pictures.”
  3290. To determine the number of contours in a shape, use the GXCountShapeContours function, which is described on page 2-116.
  3291. To determine the index of a particular geometric point within a shape, use the GXGetShapeIndex function, which is described in the next section.
  3292. GXGetShapeIndex  
  3293.  
  3294. You can use the GXGetShapeIndex function to determine the contour index of a geometric point.
  3295. long GXGetShapeIndex(gxShape source, long contour, long vector);
  3296. source    A reference to the shape containing the desired geometric point.
  3297. contour    The index of the contour within the shape containing the geometric point.
  3298. vector    The index of the geometric point within that contour.
  3299. function result    The geometric index of the specified geometric point.
  3300. DESCRIPTION
  3301. The GXGetShapeIndex function returns as its function result the contour index of the geometric point in the source shape’s geometry that is identified by the contour and vector parameters.
  3302. Each geometric point in a geometry has a geometric index—if you consider a geometry as a list of geometric points starting from the first geometric point of the first contour to the last geometric point of the last contour, the geometric of a particular geometric point is its position in this list. For example, for a shape with two contours, the first with 10 geometric points and the second with 5 geometric points, this function would return 14 if you set the contour parameter to 2 and the vector parameter to 4.
  3303. For the geometric shapes with only one contour—points, lines, curves, and rectangles— you must pass a 1 in the contour parameter. For polygons and paths shapes, the value you provide for the contour parameter must be greater than 0 and must be equal to or less than the actual number of contours in the shape. Otherwise, the function posts a contour_out_of_range warning. Similarly, the value you provide for the vector parameter must be equal to or less than the actual number of geometric points in the specified contour, or the function posts an index_out_of_range_in_contour warning.
  3304. ERRORS, WARNINGS, AND NOTICES
  3305. Errors    
  3306. out_of_memory    
  3307. shape_is_nil    
  3308. index_is_less_than_zero    
  3309. Warnings    
  3310. graphic_type_does_not_contain_points    
  3311. contour_out_of_range    
  3312. index_out_of_range_in_contour    
  3313.  
  3314. SEE ALSO
  3315. For a discussion of geometric points, see the section “About Geometric Shapes” beginning on page 2-5.
  3316. To learn how this function works for typographic shape types, see Inside Macintosh: QuickDraw GX Typography.
  3317. To learn how this function works for bitmap and picture shape types, see Chapter 5, “Bitmaps,” and Chapter 6, “Pictures.”
  3318. To determine the number of contours in a shape, use the GXCountShapeContours function, which is described on page 2-116.
  3319. To determine the number of geometric points in a contour, use the GXCountShapePoints function, which is described on page 2-116.
  3320. To copy a range of geometric points from a shape’s geometry, use the GXGetShapePoints function, which is described in the next section.
  3321. GXGetShapePoints  
  3322.  
  3323. You can use the GXGetShapePoints function to obtain a copy of a range of geometric points from a specified shape.
  3324. long GXGetShapePoints(gxShape source, long index, long count, 
  3325.                             gxPoint data[]);
  3326. source    A reference to the shape containing the desired geoemtric points.
  3327. index    The geometric index of the first geometric point to copy.
  3328. count    The number of the geometric points to copy. You may provide the gxSelectToEnd constant for this parameter.
  3329. data    A pointer to an array to hold the returned geometric points.
  3330. function result    The number of geometric points copied.
  3331. DESCRIPTION
  3332. The GXGetShapePoints function returns in the data parameter a copy of the geometric points from the source shape’s geometry starting from the geometric point with the geometric index indicated in the index parameter. 
  3333. You provide, in the count parameter, the number of geoemtric points you want copied. The function result is the actual number of points copied. Typically, the value you provide for the count parameter is the same as the function result returned by this function. There are two exceptions:
  3334. n    If you provide too large a value for the count parameter—that is, the geometry of the source shape does not have enough geometric points to satisfy your request—this function copies as many geometric points as the shape does have (starting from the geometric point with the geometric index indicated by the index parameter). In this case, the function posts a count_out_of_range warning, and the function result reflects the actual number of geometric points copied.
  3335. n    Similarly, if you set the count parameter to the the gxSelectToEnd constant, the function copies as many geometric points as the shape has, starting from the geometric point with the geometric index indicated by the index parameter. In this case, the function result reflects the actual number of geometric points copied, but no warning is posted.
  3336. Notice that this function returns the copied points as a single point array. If the source shape is a polygon or path shape, the information about which contours contained the geometric points is not retained.
  3337. If you want use the gxSelectToEnd constant for the count parameter, you would typically do the following:
  3338.     1.    Determine the length of the point array by calling this function, passing nil for the data parameter.
  3339.     2.    Allocate enough memory to hold the point array.
  3340.     3.    Call this function again, passing a pointer to the allocated memory in the data parameter.
  3341. ERRORS, WARNINGS, AND NOTICES
  3342. Errors    
  3343. out_of_memory    
  3344. shape_is_nil    
  3345. index_is_less_than_zero    
  3346. count_is_less_than_zero    
  3347. Warnings    
  3348. graphic_type_does_not_contain_points    
  3349. index_out_of_range_in_contour    
  3350. index_out_of_range    
  3351. count_out_of_range    
  3352.  
  3353. SEE ALSO
  3354. For a discussion of geometric points, see the section “Shape Geometry” beginning on page 2-8.
  3355. To learn how this function works for typographic shape types, see Inside Macintosh: QuickDraw GX Typography.
  3356. To learn how this function works for bitmap and picture shape types, see Chapter 5, “Bitmaps,” and Chapter 6, “Pictures.”
  3357. To determine the geometric index of a particular geometric point within a shape’s geometry, use the GXGetShapeIndex function, which is described on page 2-117.
  3358. To replace a range of geometric points in a geometry, use the GXSetShapePoints function, which is described in the next section.
  3359. GXSetShapePoints  
  3360.  
  3361. You can use the GXSetShapePoints procedure to replace geometric points of a shape.
  3362. void GXSetShapePoints(gxShape target, long index, long count, 
  3363.                              const gxPoint data[]);
  3364. target    A reference to the shape containing the geometric points you want to replace.
  3365. index    The index number of the first geometric point to replace.
  3366. count    The number of the geometric points to replace.
  3367. data    An array of new geometric points.
  3368. DESCRIPTION
  3369. The GXSetShapePoints function changes the values of the number of geometric points specified in the count parameter, starting with the geometric point indicated by the index parameter, to the values specified by the data parameter.
  3370. Notice that this function replaces geometric points on a point-by-point basis; the number of points in the data parameter must match the value of the count parameter. You may not use the gxSelectToEnd constant for the count parameter.
  3371. ERRORS, WARNINGS, AND NOTICES
  3372. Errors    
  3373. out_of_memory    
  3374. shape_is_nil    
  3375. index_is_less_than_zero    
  3376. count_is_less_than_zero    
  3377. Warnings    
  3378. graphic_type_does_not_contain_points    
  3379. index_out_of_range_in_contour    
  3380. index_out_of_range    
  3381. count_out_of_range    
  3382. shape_access_not_allowed    
  3383.  
  3384. SEE ALSO
  3385. For a discussion of geoemtric points, see the section “Shape Geometry” beginning on page 2-8.
  3386. For examples of this function, see “Replacing Geometric Points” beginning on page 2-68.
  3387. To learn how this function works for typographic shape types, see Inside Macintosh: QuickDraw GX Typography.
  3388. To learn how this function works for bitmap and picture shape types, see Chapter 5, “Bitmaps,” and Chapter 6, “Pictures.”
  3389. To determine the geometric index of a particular geometric point within a shape, use the GXGetShapeIndex function, which is described on page 2-117.
  3390. To obtain a copy of a range of geometric points in a geometry, use the GXGetShapePoints function, which is described on page 2-119.
  3391. GXGetPolygonParts  
  3392.  
  3393. You can use the GXGetPolygonParts function to copy of a specifed range of geometric points from the geometry of a polygon shape and then put these points into a polygon structure.
  3394. long GXGetPolygonParts(gxShape source, long index, long count,
  3395.                               gxPolygons *data);
  3396. source    A reference to the polygon shape containing the desired geometric points.
  3397. index    The geometric index of the first geometric point to copy.
  3398. count    The number of the geometric points to copy. You may provide the gxSelectToEnd constant for this parameter.
  3399. data    A pointer to a polygon structure to hold the copied geometric information.
  3400. function result    The number of bytes required to hold the information returned in the data parameter.
  3401. DESCRIPTION
  3402. The GXGetPolygonParts function copies geometry information from the source polygon shape into the polygon structure specified by the data parameter. This function copies all of the geometric information starting with the geometric point indicated by the index parameter and continuing for as many geometric points as indicated by the count parameter. This function copies the values of the indicated geometric points and retains the information about contour breaks from the original geometry. The function result is the length in bytes of the information returned in the data parameter.
  3403. Both the index and the count parameters must be greater than 0, although you can provide the gxSelectToEnd constant for the count parameter, which indicates that you want a copy of all the geometric points starting with the point indicated by the index parameter.
  3404. You may pass nil for the data parameter. In this case, the function still returns the byte length as the function result, but does not copy any geometric information.
  3405. Typically, to use this function, you go through these steps:
  3406.     1.    Determine the byte length needed to store the copied geometric information by calling this function, passing nil for the data parameter.
  3407.     2.    Allocate enough memory to hold the copied geometric information.
  3408.     3.    Call this function again, passing a pointer to the allocated memory in the data parameter.
  3409. ERRORS, WARNINGS, AND NOTICES
  3410. Errors    
  3411. out_of_memory    
  3412. shape_is_nil    
  3413. illegal_type_for_shape    
  3414. index_is_less_than_zero    
  3415. count_is_less_than_zero    
  3416. Warnings    
  3417. index_out_of_range    
  3418. count_out_of_range    
  3419.  
  3420. SEE ALSO
  3421. For a discussion of polygons, see “Polygon Shapes” on page 2-20.
  3422. For the definition of the gxPolygons structure, see page 2-92.
  3423. For an example of this function, see “Editing Polygon Parts” beginning on page 2-71.
  3424. For information about other functions that allow you to extract information from shape geometries, see the description of the GXGetShapePoints function on page 2-119 and the description of the GXGetShapeParts function on page 2-129.
  3425. To replace parts of a polygon shape’s geometry, use the GXSetPolygonParts function, which is described in the next section.
  3426. GXSetPolygonParts  
  3427.  
  3428. You can use the GXSetPolygonParts function to replace a range of geometric information in the geometry of a polygon shape with information from a specified polygon structure.
  3429. void GXSetPolygonParts(gxShape target, long index, long count, 
  3430.                               const gxPolygons *data, 
  3431.                               gxEditShapeFlag flags);
  3432. target    A reference to the polygon shape whose geometry you want to edit.
  3433. index    The geometric index of the first geometric point to replace. A value of 0 indicates that the new information should be inserted after the final geometric point in the target shape’s geometry.
  3434. count    The number of the geometric points to replace. A value of 0 indicates that no geometric points should be replaced; instead, the new information is inserted before the geometric point indicated by the index parameter. If you pass the gxSelectToEnd constant for this parameter, all geometric points starting with the geometric point indicated by the index parameter are replaced.
  3435. data    A pointer to a polygon structure containing the new geometric information.
  3436. flags    A set of flags that determine how the new information is inserted in the existing geometry.
  3437. DESCRIPTION
  3438. The GXSetPolygonParts function replaces geometric information in the target shape’s geometry with the information pointed to by the data parameter. The index and count parameters determine what part of the original geometry is replaced. The flags parameter determines how the new information is inserted in the geometry.
  3439. The data parameter contains a pointer to the geometric information to be copied into the target shape’s geometry. If you pass the gxSetToNil constant for this parameter, no new information is copied in; in this case, this function removes the indicated geometric points instead of replacing them.
  3440. The index parameter indicates the first geometric point to be replaced. If you pass a value of 0 for this parameter, no geometric points are replaced. Instead, this function inserts the new geometric information after the last geometric point of the target shape’s original geometry. If you pass a 0 for this parameter, you must pass a 0 or the gxSelectToEnd constant for the count parameter.
  3441. The count parameter indicates how many geometric points in the original geometry should be replaced. If you pass a value of 0 for this parameter, no geometric points are replaced; instead, this function inserts the new geometric information before the geometric point indicated by the index parameter. If you pass the gxSelectToEnd constant for this parameter, the function replaces all geometric points in the original geometry starting with the geometric point indicated by the index parameter.
  3442. When this function inserts the new geometric information, it retains the contour breaks contained in the gxPolygons structure specified by the data parameter. For example, if you provide a gxPolygons structure that contains two contours, the break between those contours remains when the new geometric points are inserted into the target shape’s geometry.
  3443. The flags parameter indicates how you want the function to merge the first geometric point and the last geometric point of the gxPolygons structure into the target shape’s geometry. The possible flags are:
  3444. gxBreakNeitherEdit                                    = 0
  3445. breakLeft            Edit                        = 0x01
  3446. breakRight            Edit                        = 0x02
  3447. removeDuplicatePoints                                    = 0x04
  3448. The gxBreakLeftEdit flag indicates that the first geometric point of the gxPolygons structure should begin a new contour in the target shape’s geometry. The gxBreakRightEdit flag indicates that geometric point in the target shape which follows the final geometric point of the gxPolygons structure (after the new information is inserted) should begin a new contour.
  3449. The gxBreakNeitherEdit value indicates that the first geometric point of the gxPolygons structure should be merged into preceding contour of the target shape’s geometry and the final geometric point of the gxPolygons structure should be merged into the following contour.
  3450. The removeDuplicatePoints flag indicates that this function should, when inserting the information from the gxPolygons structure, remove the first geometric point of this structure if it exactly matches the preceding geoemtric point. Similarly, this flag indicates that the final geometric point of the gxPolygons structure should be removed if it exactly matches the subsequent geometric point in the target shape’s geometry.
  3451. ERRORS, WARNINGS, AND NOTICES
  3452. Errors    
  3453. out_of_memory    
  3454. shape_is_nil    
  3455. illegal_type_for_shape    
  3456. inconsistent_parameters    
  3457. index_is_less_than_zero    
  3458. count_is_less_than_zero    
  3459. number_of_points_exceeds_implementation_limit    
  3460. number_of_contours_exceeds_implementation_limit    
  3461. size_of_polygon_exceeds_implementation_limit    
  3462. Warnings    
  3463. index_out_of_range    
  3464. count_out_of_range    
  3465.  
  3466. SEE ALSO
  3467. For a discussion of polygons, see “Polygon Shapes” on page 2-20.
  3468. For the definition of the gxPolygons structure, see page 2-92.
  3469. For an example of this function, see “Editing Polygon Parts” beginning on page 2-71.
  3470. For information about other functions that allow you to edit information in shape geometries, see the description of the GXSetShapePoints function on page 2-121 and the description of the GXSetShapeParts function on page 2-131.
  3471. To copy parts of a polygon shape’s geometry, use the GXGetPolygonParts function, which is described on page 2-122.
  3472. GXGetPathParts  
  3473.  
  3474. You can use the GXGetPathParts function to extract a copy of a specifed range of geometric points from the geometry of a path shape and put them these points into a gxPaths structure.
  3475. long GXGetPathParts(gxShape source, long index, long count, 
  3476.                           gxPaths *data);
  3477. source    A reference to the path shape containing the desired geometric points.
  3478. index    The geometric index of the first geometric point to copy.
  3479. count    The number of the geometric points to copy. You may provide the gxSelectToEnd constant for this parameter.
  3480. data    A pointer to a gxPaths structure to hold the copied geometric information.
  3481. function result    The number of bytes required to hold the information returned in the data parameter.
  3482. DESCRIPTION
  3483. The GXGetPathParts function copies geometric information from the source path shape into the gxPaths structure specified by the data parameter. This function copies all of the geometric information starting with the geometric point indicated by the index parameter and continuing for as many geometric points as indicated by the count parameter. This function copies the values of the indicated geometric points and retains the information about contour breaks from the original geometry, as well as the information about which points are on curve and which are off curve. The function result is the length in bytes of the information returned in the data parameter.
  3484. Both the index and and the count parameters must be greater than 0, although you can provide the gxSelectToEnd constant for the count parameter, which indicates that you want a copy of all the geometric points starting with the geometric point indicated by the index parameter.
  3485. You may pass nil for the data parameter. In this case, the function still returns the byte length as the function result, but does not copy any geometric information.
  3486. Typically, to use this function, you go through these steps:
  3487.     1.    Determine the byte length needed to store the copied geometry information by calling this function, passing nil for the data parameter.
  3488.     2.    Allocate enough memory to hold the copied geometry information.
  3489.     3.    Call this function again, passing a pointer to the allocated memory in the data parameter.
  3490. ERRORS, WARNINGS, AND NOTICES
  3491. Errors    
  3492. out_of_memory    
  3493. shape_is_nil    
  3494. illegal_type_for_shape    
  3495. index_is_less_than_zero    
  3496. count_is_less_than_zero    
  3497. Warnings    
  3498. index_out_of_range    
  3499. count_out_of_range    
  3500.  
  3501. SEE ALSO
  3502. For a discussion of paths, see “Path Shapes” on page 2-23.
  3503. For the definition of the gxPaths structure, see page 2-93.
  3504. For information about other functions that allow you to extract information from shape geometries, see the description of the GXGetShapePoints function on page 2-119 and the description of the GXGetShapeParts function on page 2-129.
  3505. To replace parts of a path shape’s geometry, use the GXSetPathParts function, which is described in the next section.
  3506. GXSetPathParts  
  3507.  
  3508. You can use the GXSetPathParts function to replace a range of geometric points in the geometry of a path shape with the information from a specified gxPaths structure.
  3509. void GXSetPathParts(gxShape target, long index, long count, 
  3510.                           const gxPaths *data, gxEditShapeFlag flags);
  3511. target    A reference to the path shape whose geometry you want to edit.
  3512. index    The index number of the first geometric point to replace. A value of 0 indicates that the new information should be inserted after the final geometric point in the target shape’s geometry.
  3513. count    The number of the geometric points to replace. A value of 0 indicates that no geometric points should be replaced; instead, the new information is inserted before the geometric point specified by the index parameter. If you pass the gxSelectToEnd constant for this parameter, all geometric points from the one specified by the index parameter to the final geometric point are replaced.
  3514. data    A pointer to the gxPaths structure containing the new geometry information.
  3515. flags    A set of flags that determine how the new information is inserted in the existing geometry.
  3516. DESCRIPTION
  3517. The GXSetPathParts function replaces geometry information in the target shape’s geometry with the information pointed to by the data parameter. The index and count parameters determine what part of the original geometry is replaced. The flags parameter determines how the new information is inserted in the geometry.
  3518. The data parameter contains a pointer to the geometry information to be copied into the target shape’s geometry. If you pass the gxSetToNil constant for this parameter, no new information is copied in; in this case, the GXSetPathParts function removes the indicated geometric points instead of replacing them.
  3519. The index parameter indicates the first geometric point to be replaced. If you pass a value of 0 for this parameter, no geometric points are replaced. Instead, this function inserts the new geometric information after the last geometric point of the target shape’s original geometry. If you pass a 0 for this parameter, you must pass a 0 or the gxSelectToEnd constant for the count parameter.
  3520. The count parameter indicates how many geometric points in the original geometry should be replaced. If you pass a value of 0 for this parameter, no geometric points are replaced; instead, this function inserts the new geometric information before the geometric point indicated by the index parameter. If you pass the gxSelectToEnd constant for this parameter, the function replaces all geometric points in the original geometry starting with the one indicated by the index parameter.
  3521. When this function inserts the new geometric information, it retains the contour breaks contained in the gxPaths structure specified in the data parameter. For example, if you provide a gxPaths structure that contains two contours, the break between those contours remains when the geometric points are inserted into the target shape’s geometry.
  3522. The flags parameter indicates how you want the function to merge the first geometric point and the last geometric point of the gxPaths structure into the target shape’s geometry. The possible flags are
  3523. gxBreakNeitherEdit                                    = 0
  3524. breakLeft            Edit                        = 0x01
  3525. breakRight            Edit                        = 0x02
  3526. removeDuplicatePoints                                    = 0x04
  3527. The gxBreakLeftEdit flag indicates that the first geometric point of the gxPaths structure should begin a new contour once inserted into the target shape’s geometry. The gxBreakRightEdit flag indicates that geometric point in the target shape that follows the final geometric point of the gxPaths structure (after the new information is inserted) should begin a new contour.
  3528. The gxBreakNeitherEdit value indicates that the first geometric point of the gxPaths structure should be merged into preceding contour of the target shape’s geometry and the final geometric point of the gxPaths structure should be merged into the subsequent contour.
  3529. The removeDuplicatePoints flag indicates that this function should, when inserting the information from the gxpaths structure, remove the first geometric point of this inserted structure if it exactly matches the preceding point in the existing geometry. Similarly, this flag indicates that the final geometric point of the gxPaths structure should be removed if it exactly matches the subsequent geometric point in the target shape’s geometry.
  3530. ERRORS, WARNINGS, AND NOTICES
  3531. Errors    
  3532. out_of_memory    
  3533. shape_is_nil    
  3534. illegal_type_for_shape    
  3535. inconsistent_parameters    
  3536. index_is_less_than_zero    
  3537. count_is_less_than_zero    
  3538. number_of_points_exceeds_implementation_limit    
  3539. number_of_contours_exceeds_implementation_limit    
  3540. size_of_path_exceeds_implementation_limit    
  3541. Warnings    
  3542. index_out_of_range    
  3543. count_out_of_range    
  3544.  
  3545. SEE ALSO
  3546. For a discussion of paths, see “Path Shapes” on page 2-23.
  3547. For the definition of the gxPaths structure, see “Path Structures” on page 2-93.
  3548. For an example of this function, see “Editing Paths Parts” beginning on page 2-79.
  3549. For information about other functions that allow you to edit information in shape geometries, see the description of the GXSetShapePoints function on page 2-121 and the description of the GXSetShapeParts function on page 2-131.
  3550. To copy parts of a path shape’s geometry, use the GXGetPathParts function, which is described on page 2-126.
  3551. GXGetShapeParts  
  3552.  
  3553. You can use the GXGetShapeParts function to extract a copy of a specifed range of geometric points from the geometry of one shape and encapsulate it into another shape.
  3554. gxShape GXGetShapeParts(gxShape source, long index, long count, 
  3555.                                   gxShape destination);
  3556. source    A reference to the shape containing the desired geometric points.
  3557. index    The geometric indexof the first geometric point to copy.
  3558. count    The number of the geometric points to copy. You may provide the gxSelectToEnd constant for this parameter.
  3559. destination    
  3560. A reference to the shape to encapsulate the copied geometric information.
  3561. function result    A copy of the reference returned in the destination parameter.
  3562. DESCRIPTION
  3563. The GXGetShapeParts function copies geometric information from the source shape into the destination shape. This function copies all of the geometric information starting with the geometric point indicated by the index parameter and continuing for as many geometric points as indicated by the count parameter. This function copies the values of the indicated geometric points and retains the information about contour breaks from the original geometry, as well as the information about which points are on curve and which are off curve. As a convenience, the function returns as its function result a reference to the destination shape.
  3564. Both the index and and the count parameters must be greater than 0, although you can provide the gxSelectToEnd constant for the count parameter, which indicates that you want a copy of all the geometric points (starting with the geometric point indicated by the index parameter) in the source shape’s geometry.
  3565. You may pass nil for the destination parameter. In this case, the function creates a new shape of the appropriate type and encapsulates the extracted geometric information in this new shape.
  3566. If the source shape is a point, the destination shape will be a point as well.
  3567. If the source shape is a line, the destination shape will be a point or a line, depending on the number of geometric points copied.
  3568. If the source shape is a curve, the destination shape will be a point, line, or curve, depending on the number of geometric points copied.
  3569. If the source shape is a rectangle, the destination shape will be a point or a rectangle, depending on the number of geometric points copied.
  3570. If the source shape is a polygon or a path shape, the destination shape will also be a polygons or a paths shape, even if only one or two geometric points are copied.
  3571. SPECIAL CONSIDERATIONS
  3572. If you pass nil for the destination parameter and no error results, the GXGetShapeParts function creates a shape; you are responsible for disposing of this shape when you no longer need it. See Inside Macintosh: QuickDraw GX Objects for information about creating and disposing of objects.
  3573. ERRORS, WARNINGS, AND NOTICES
  3574. Errors    
  3575. out_of_memory    
  3576. shape_is_nil    
  3577. index_is_less_than_zero    
  3578. count_is_less_than_zero    
  3579. Warnings    
  3580. shape_operator_may_not_be_a_bitmap    
  3581. index_out_of_range    
  3582. count_out_of_range    
  3583.  
  3584. SEE ALSO
  3585. To learn how this function works for typographic shape types, see Inside Macintosh: QuickDraw GX Typography.
  3586. To learn how this function works for bitmap and picture shape types, see Chapter 5, “Bitmaps,” and Chapter 6, “Pictures.”
  3587. For information about other functions that allow you to extract information from shape geometries, see the description of the GXGetShapePoints function on page 2-119, the description of the GXGetPolygonParts function on page 2-122, and the description of the GXGetPathParts function on page 2-126.
  3588. To replace parts of a shape’s geometry, use the GXSetShapeParts function, which is described in the next section.
  3589. GXSetShapeParts  
  3590.  
  3591. You can use the GXSetShapeParts function to replace a range of geometric points in a shape’s geometry with the information in another shape’s geometry.
  3592. void GXSetShapeParts(gxShape target, long index, long count, 
  3593.                            gxShape insert, gxEditShapeFlag flags);
  3594. target    A reference to the shape whose geometry you want to edit.
  3595. index    The geometric index of the first geometric point to replace. A value of 0 indicates that the new information should be inserted after the final geometric point in the target shape’s geometry.
  3596. count    How many geometric points to replace. A value of 0 indicates that no geometric points should be replaced; instead, the new information is inserted before the geometric point specified by the index parameter. If you pass the gxSelectToEnd constant for this parameter, all geometric points from the one specified by the index parameter to the final one are replaced.
  3597. insert    The shape whose geometry you want to insert.
  3598. flags    A set of flags that determine how the new geometry information is inserted in the target shape’s geometry.
  3599. DESCRIPTION
  3600. The GXSetShapeParts function replaces geometric information in the target shape’s geometry with the geometric information in the shape specified by the insert parameter. The index and count parameters determine what part of the original geometry is replaced. The flags parameter determines how the new information is inserted into the geometry.
  3601. This function converts the shape type of the target shape to be suitable to hold the information from the inserted shape. For example, if the target shape is a line and the inserted shape is a rectangle, this function converts the target shape to a polygon shape before inserting the rectangle.
  3602. If the target shape is a rectangle, you may only insert information before both geometric points, after both geometric points, or in place of both geometric points.
  3603. You may add any shape to an empty target shape—the result will identical to the inserted shape. You may also add any shape to a full target shape, but the result will also be a full shape.
  3604. The index parameter indicates the first geometric point to be replaced. If you pass a value of 0 for this parameter, no geometric points are replaced. Instead, this function inserts the new geometric information after the last geometric point of the target shape’s original geometry. If you pass a 0 for this parameter, you must pass a 0 or the gxSelectToEnd constant for the count parameter.
  3605. The count parameter indicates how many geometric points in the original geometry should be replaced. If you pass a value of 0 for this parameter, no geometric points are replaced; instead, this function inserts the new geometric information before the geometric point indicated by the index parameter. If you pass the gxSelectToEnd constant for this parameter, the function replaces all geometric points in the original geometry starting with the geometric point indicated by the index parameter.
  3606. When this function inserts the new geometry information, it retains the contour breaks contained in the inserted shape’s geometry. For example, if you provide a path shape for the inserted shape that contains two contours, the break between those contours remains when the geometric points are inserted into the target shape’s geometry.
  3607. The flags parameter indicates how you want the function to merge the first geometric point and the last geometric point of the inserted shape’s geometry into the target shape’s geometry. The possible flags are:
  3608. gxBreakNeitherEdit                                    = 0
  3609. breakLeft            Edit                        = 0x01
  3610. breakRight            Edit                        = 0x02
  3611. removeDuplicatePoints                                    = 0x04
  3612. The gxBreakLeftEdit flag indicates that the first geometric point of the inserted shape’s geometry should begin a new contour once inserted into the target shape’s geometry. The gxBreakRightEdit flag indicates that geometric point in the target shape which follows the final geometric point of the inserted shape’s geometry (after the new information is inserted) should begin a new contour.
  3613. The gxBreakNeitherEdit value indicates that the first geometric point of the inserted shape’s geometry should be merged into preceding contour of the target shape’s geometry and the final geometric point of the inserted shape’s geometry should be merged into the subsequent contour.
  3614. The removeDuplicatePoints flag indicates that this function should, when inserting the information from the inserted shape’s geometry, remove the first geometric point of this inserted geometry if it exactly matches the preceding point in the existing geometry. Similarly, this flag indicates that the final geometric point of the inserted shape’s geometry should be removed if it exactly matches the subsequent geometric point in the target shape’s geometry.
  3615. ERRORS, WARNINGS, AND NOTICES
  3616. Errors    
  3617. out_of_memory    
  3618. shape_is_nil    
  3619. index_is_less_than_zero    
  3620. count_is_less_than_zero    
  3621. Warnings    
  3622. rectangles_cannot_be_inserted_into    
  3623. shape_operator_may_not_be_a_bitmap    
  3624. index_out_of_range    
  3625. count_out_of_range    
  3626. picture_cannot_contain_itself    
  3627.  
  3628. SEE ALSO
  3629. For an example of this function, see “Editing Shape Parts” beginning on page 2-81.
  3630. To learn how this function works for typographic shape types, see Inside Macintosh: QuickDraw GX Typography.
  3631. To learn how this function works for bitmap and picture shape types, see Chapter 5, “Bitmaps,” and Chapter 6, “Pictures.”
  3632. For information about other functions that allow you to edit information in shape geometries, see the description of the GXSetShapePoints function on page 2-121, the description of the GXSetPolygonParts function on page 2-123, and the description of the GXSetPathParts function on page 2-127.
  3633. To copy parts of a shape’s geometry, use the GXGetShapeParts function, which is described on page 2-129.
  3634. Drawing Geometric Shapes
  3635.  
  3636. The QuickDraw GX drawing functions compile all of the information in a shape’s properties, and the properties of its style, ink, and transform objects, and produce a graphic image. Therefore, to understand how these functions draw geometric shapes, you need to be familiar with much of the information in Inside Macintosh: QuickDraw GX Objects, as well as much of the information in this chapter and in the next chapter, “Geometric Styles.” The function descriptions in this section give an overview of the process these functions use to draw geometric shapes.
  3637. To draw a shape once you have created it and modified its properties to suite your needs, you call the GXDrawShape function. This function draws all shape types, and is described in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  3638. If you want to draw a geometric shape without creating a shape object—that is, just given a geometry—you can use the GXDrawPoint, GXDrawLine, GXDrawCurve, GXDrawRectangle, GXDrawPolygons, or GXDrawPaths functions, which are described in this section.
  3639. GXDrawPoint  
  3640.  
  3641. You can use the GXDrawPoint function to draw a point without creating a point shape.
  3642. void GXDrawPoint(const gxPoint *data);
  3643. data    A pointer to the point geometry you want to draw.
  3644. DESCRIPTION
  3645. The GXDrawPoint function draws the point geometry specified by the data parameter, using the shape fill, style, ink, and transform of the default point shape.
  3646. ERRORS, WARNINGS, AND NOTICES
  3647. Errors    
  3648. out_of_memory    
  3649. parameter_is_nil    
  3650.  
  3651. SEE ALSO
  3652. For more information about points and the default point shape, see “Point Shapes” on page 2-15.
  3653. For the definition of the gxPoint structure, see page 2-90.
  3654. For examples using this function, see “Creating and Drawing Points” beginning on page 2-27.
  3655. For more information about drawing shapes, see the description of the GXDrawShape function in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  3656. GXDrawLine  
  3657.  
  3658. You can use the GXDrawLine function to draw a line without creating a line shape.
  3659. void GXDrawLine(const gxLine *data);
  3660. data    A pointer to the line geometry you want to draw.
  3661. DESCRIPTION
  3662. The GXDrawLine function draws the line geometry specified by the data parameter, using the shape fill, style, ink, and transform of the default line shape.
  3663. ERRORS, WARNINGS, AND NOTICES
  3664. Errors    
  3665. out_of_memory    
  3666. parameter_is_nil    
  3667.  
  3668. SEE ALSO
  3669. For more information about lines and the default line shape, see “Line Shapes” on page 2-16.
  3670. For the definition of the gxLine structure, see “Line Structure” on page 2-91.
  3671. For examples using this function, see “Creating and Drawing Lines” beginning on page 2-32.
  3672. For more information about drawing shapes, see the description of the GXDrawShape function in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  3673. GXDrawCurve  
  3674.  
  3675. You can use the GXDrawCurve function to draw a curve without creating a curve shape.
  3676. void GXDrawCurve(const gxCurve *data);
  3677. data    A pointer to the curve geometry you want to draw.
  3678. DESCRIPTION
  3679. The GXDrawCurve function draws the curve geometry specified by the data parameter, using the shape fill, style, ink, and transform of the default curve shape.
  3680. ERRORS, WARNINGS, AND NOTICES
  3681. Errors    
  3682. out_of_memory    
  3683. parameter_is_nil    
  3684.  
  3685. SEE ALSO
  3686. For more information about curves and the default curve shape, see “Curve Shapes” on page 2-17.
  3687. For the definition of the gxCurve structure, see page 2-91.
  3688. For examples using this function, see “Creating and Drawing Curves” beginning on page 2-39.
  3689. For more information about drawing shapes, see the description of the GXDrawShape function in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects
  3690. GXDrawRectangle  
  3691.  
  3692. You can use the GXDrawRectangle function to draw a rectangle without creating a rectangle shape.
  3693. void GXDrawRectangle(const gxRectangle *data, gxShapeFill fill);
  3694. data    A pointer to the rectangle geometry you want to draw.
  3695. fill    The shape fill to use when drawing the rectangle.
  3696. DESCRIPTION
  3697. The GXDrawRectangle function draws the rectangle geometry specified by the data parameter, using the shape fill specified by the fill parameter, and the style, ink, and transform of the default rectangle shape.
  3698. ERRORS, WARNINGS, AND NOTICES
  3699. Errors    
  3700. out_of_memory    
  3701. parameter_is_nil    
  3702.  
  3703. SEE ALSO
  3704. For more information about rectangles and the default rectangle shape, see “Rectangle Shapes” on page 2-19.
  3705. For the definition of the gxRectangle structure, see page 2-91.
  3706. For examples using this function, see “Creating and Drawing Rectangles” beginning on page 2-36.
  3707. For more information about drawing shapes, see the description of the GXDrawShape function in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  3708. GXDrawPolygons  
  3709.  
  3710. You can use the GXDrawPolygons function to draw polygons without creating a polygon shape.
  3711. void GXDrawPolygons(const gxPolygons *data, gxShapeFill fill);
  3712. data    A pointer to the polygon geometry you want to draw.
  3713. fill    The shape fill to use when drawing the polygon.
  3714. DESCRIPTION
  3715. The GXDrawPolygons function draws the polygons geometry specified by the data parameter, using the shape fill specified by the fill parameter, and the style, ink, and transform of the default polygon shape.
  3716. ERRORS, WARNINGS, AND NOTICES
  3717. Errors    
  3718. out_of_memory    
  3719. parameter_is_nil    
  3720.  
  3721. SEE ALSO
  3722. For more information about polygons and the default polygons shape, see “Polygon Shapes” on page 2-20.
  3723. For the definition of the gxPolygons structure, see page 2-92.
  3724. For examples using this function, see “Creating and Drawing Polygons” beginning on page 2-40.
  3725. For more information about drawing shapes, see the description of the GXDrawShape function in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  3726. GXDrawPaths  
  3727.  
  3728. You can use the GXDrawPaths function to draw a path geometry without creating a path shape.
  3729. void GXDrawPaths(const gxPaths *data, gxShapeFill fill);
  3730. data    A pointer to the path geometry you want to draw.
  3731. fill    The shape fill to use when drawing the path contours.
  3732. DESCRIPTION
  3733. The GXDrawPaths function draws the path geometry specified by the data parameter, using the shape fill specified by the fill parameter, and the style, ink, and transform of the default paths shape.
  3734. ERRORS, WARNINGS, AND NOTICES
  3735. Errors    
  3736. out_of_memory    
  3737. parameter_is_nil    
  3738.  
  3739. SEE ALSO
  3740. For more information about paths and the default paths shape, see “Path Shapes” on page 2-23.
  3741. For the definition of the gxPaths structure, see page 2-93.
  3742. For examples using this function, see “Creating and Drawing Paths” beginning on page 2-49.
  3743. For more information about drawing shapes, see the description of the GXDrawShape function in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  3744.  
  3745.  
  3746. Summary of Geometric Shapes
  3747.  
  3748. Constants and Data Types
  3749.  
  3750. Point Structure
  3751. struct gxPoint{
  3752.     fixed            x;
  3753.     fixed            y;
  3754. };
  3755. Line Structure
  3756. struct gxLine {
  3757.     struct gxPoint             first;
  3758.     struct gxPoint             last;
  3759. };
  3760. Curves
  3761. struct gxCurve {
  3762.     struct gxPoint             first;
  3763.     struct gxPoint             control;
  3764.     struct gxPoint             last;
  3765. };
  3766. Rectangle Structure
  3767. struct gxRectangle {
  3768.     fixed            left;
  3769.     fixed            top;
  3770.     fixed            right;
  3771.     fixed            bottom;
  3772. };
  3773. Polygon Structures
  3774. struct gxPolygon {
  3775.     long                    vectors;
  3776.     struct gxPoint                 vector[gxAnyNumber];
  3777. };
  3778. struct gxPolygons{
  3779.     long                      contours;
  3780.     struct gxPolygon                 contour[gxAnyNumber];
  3781. };
  3782. Path Structures
  3783. struct gxPath {
  3784.     long                    vectors;
  3785.     long                    controlBits[gxAnyNumber];
  3786.     struct gxPoint             vector[gxAnyNumber];
  3787. };
  3788. struct gxPaths {
  3789.     long                   contours;
  3790.     struct gxPath             contour[gxAnyNumber];
  3791. };
  3792. Functions
  3793.  
  3794. Creating Geometric Shapes
  3795. gxShape GXNewPoint    (const gxPoint *data);
  3796. gxShape GXNewLine    (const gxLine *data);
  3797. gxShape GXNewCurve    (const gxCurve *data);
  3798. gxShape GXNewRectangle    (const gxRectangle *data);
  3799. gxShape GXNewPolygons    (const gxPolygons *data);
  3800. gxShape GXNewPaths    (const gxPaths *data);
  3801. Getting and Setting Shape Geometries
  3802. gxPoint *GXGetPoint    (gxShape source, gxPoint *data);
  3803. void GXSetPoint    (gxShape target, const gxPoint *data);
  3804. gxLine *GXGetLine    (gxShape source, gxLine *data);
  3805. void GXSetLine    (gxShape target, const gxLine *data);
  3806. gxCurve *GXGetCurve    (gxShape source, gxCurve *data);
  3807. void GXSetCurve    (gxShape target, const gxCurve *data);
  3808. gxRectangle *GXGetRectangle    (gxShape source, gxRectangle *data);
  3809. void GXSetRectangle    (gxShape target, const gxRectangle *data);
  3810. long GXGetPolygons    (gxShape source, gxPolygons *data);
  3811. void GXSetPolygons    (gxShape target, const gxPolygons *data);
  3812. long GXGetPaths    (gxShape source, gxPaths *data);
  3813. void GXSetPaths    (gxShape target, const gxPaths *data);
  3814. Editing Shape Geometries
  3815. long GXCountShapeContours    (gxShape source);
  3816. long GXCountShapePoints    (gxShape source, long contour);
  3817. long GXGetShapeIndex    (gxShape source, long contour, long vector);
  3818. long GXGetShapePoints    (gxShape source, long index, long count, 
  3819. gxPoint data[]);
  3820. void GXSetShapePoints    (gxShape target, long index, long count, 
  3821. const gxPoint data[]);
  3822. long GXGetPolygonParts    (gxShape source, long index, long count,
  3823. gxPolygons *data);
  3824. void GXSetPolygonParts    (gxShape target, long index, long count, 
  3825. const gxPolygons *data, 
  3826. gxEditShapeFlag flags);
  3827. long GXGetPathParts    (gxShape source, long index, long count, 
  3828. gxPaths *data);
  3829. void GXSetPathParts    (gxShape target, long index, long count, 
  3830. const gxPaths *data, gxEditShapeFlag flags);
  3831. gxShape GXGetShapeParts    (gxShape source, long index, long count, 
  3832. gxShape destination);
  3833. void GXSetShapeParts    (gxShape target, long index, long count, 
  3834. gxShape insert, gxEditShapeFlag flags);
  3835. Drawing Geometric Shapes
  3836. void GXDrawPoint    (const gxPoint *data);
  3837. void GXDrawLine    (const gxLine *data);
  3838. void GXDrawCurve    (const gxCurve *data);
  3839. void GXDrawRectangle    (const gxRectangle *data, gxShapeFill fill);
  3840. void GXDrawPolygons    (const gxPolygons *data, gxShapeFill fill);
  3841. void GXDrawPaths    (const gxPaths *data, gxShapeFill fill);
  3842. Listing 3-0
  3843. Table 3-0
  3844. Geometric Styles
  3845. Contents
  3846. About Geometric Styles3-5
  3847. Shapes and Styles3-5
  3848. Incorporating Stylistic Variations Into Shape Geometries3-9
  3849. Style Properties3-12
  3850. Default Style Objects3-13
  3851. Curve Error3-14
  3852. The Geometric Pen3-15
  3853. Style Attributes3-17
  3854. Pen Placement3-18
  3855. Grids3-21
  3856. Caps, Joins, Dashes and Patterns3-22
  3857. Caps3-23
  3858. Joins3-25
  3859. Dashes3-27
  3860. Patterns3-31
  3861. Interactions Between Caps, Joins, Dashes, and Patterns3-33
  3862. Using Geometric Styles3-35
  3863. Associating Styles With Shapes3-36
  3864. Constraining Shape Geometries to Grids3-39
  3865. Constraining Shapes to Device Grids3-41
  3866. Converting Paths to Polygons3-43
  3867. Using Curve Error When Reducing Shapes3-46
  3868. Manipulating Pen Width and Placement3-48
  3869. Adding Caps to a Shape3-53
  3870. Adding Standard Caps to a Shape3-56
  3871. Adding Joins to a Shape3-58
  3872. Adding Standard Joins to a Shape3-61
  3873. Dashing a Shape3-63
  3874. Adjusting Dashes to Fit Contours3-67
  3875. Insetting Dashes3-69
  3876. Breaking and Bending Dashes3-71
  3877. Wrapping Text3-75
  3878. Determining Dash Positions3-77
  3879. Adding a Pattern to a Shape3-81
  3880. Determining Pattern Positions3-83
  3881. Combining Caps, Joins, Dashes, and Patterns3-86
  3882. Geometric Styles Reference3-90
  3883. Constants and Data Types3-91
  3884. Style Objects3-91
  3885. Style Attributes3-92
  3886. Cap Record Structure3-94
  3887. Cap Attributes3-95
  3888. Join Record Structure3-95
  3889. Join Attributes3-96
  3890. Dash Record Structure3-97
  3891. Dash Attributes3-98
  3892. Pattern Record Structure3-99
  3893. Pattern Attributes3-100
  3894. Functions3-101
  3895. Getting and Setting Style Attributes3-102
  3896. GXGetStyleAttributes3-102
  3897. GXSetStyleAttributes3-103
  3898. GXGetShapeStyleAttributes3-105
  3899. GXSetShapeStyleAttributes3-106
  3900. Getting and Setting Curve Error3-107
  3901. GXGetStyleCurveError 3-108
  3902. GXSetStyleCurveError 3-109
  3903. GXGetShapeCurveError 3-110
  3904. GXSetShapeCurveError 3-111
  3905. Getting and Setting the Pen Width3-112
  3906. GXGetStylePen 3-112
  3907. GXSetStylePen 3-113
  3908. GXGetShapePen 3-114
  3909. GXSetShapePen 3-115
  3910. Getting and Setting Start Caps and End Caps3-116
  3911. GXGetStyleCap 3-117
  3912. GXSetStyleCap 3-118
  3913. GXGetShapeCap 3-119
  3914. GXSetShapeCap 3-120
  3915. Getting and Setting Joins3-121
  3916. GXGetStyleJoin 3-122
  3917. GXSetStyleJoin 3-123
  3918. GXGetShapeJoin 3-124
  3919. GXSetShapeJoin 3-125
  3920. Getting and Setting Dashes3-126
  3921. GXGetStyleDash 3-126
  3922. GXSetStyleDash 3-128
  3923. GXGetShapeDash 3-129
  3924. GXSetShapeDash 3-130
  3925. GXGetShapeDashPositions 3-131
  3926. Getting and Setting Patterns3-132
  3927. GXGetStylePattern 3-133
  3928. GXSetStylePattern 3-134
  3929. GXGetShapePattern 3-135
  3930. GXSetShapePattern 3-137
  3931. GXGetShapePatternPositions 3-138
  3932. Summary of Geometric Styles3-140
  3933. Constants and Data Types3-140
  3934. Functions for Manipulating Geometric Style Properties3-142
  3935. Geometric Styles
  3936. This chapter describes the geometric properties of style objects, which you can use to apply certain types of stylistic variations to QuickDraw GX shapes. In particular, this chapter shows how you can
  3937. n    constrain the drawing of a shape to a grid
  3938. n    specify the pen width to use when drawing a shape’s frame
  3939. n    indicate the placement of the pen relative to the shape’s frame
  3940. n    specify what to draw at the beginnings and the ends of a shape’s contours
  3941. n    specify what to draw at the corners of a shape’s contours
  3942. n    dash the contours of a shape
  3943. n    fill a shape, or the frame of a shape, with a pattern
  3944. You can also apply stylistic variations to typographic shapes, using the typographic properties of the style object. For example, you can use the style associated with a text shape to specify the text’s font, font size, and text face. The chapter “Typographic Shapes and Styles” in Inside Macintosh: QuickDraw GX Typography discusses the text-related properties of style objects.
  3945. You should be familiar with some of the information in Inside Macintosh: QuickDraw GX Objects before you read this chapter; in particular, you should read the chapters “Introduction to QuickDraw GX Objects” and “Style Objects” in that book.
  3946.  
  3947. About Geometric Styles
  3948.  
  3949. A style is a group of stylistic variations applied to a shape. QuickDraw GX provides two major categories of stylistic variations: geometric variations, which include pen width, dashes, patterns, and so on, and typographic variations, which include font, font size, text face, and so on.
  3950. Both types of stylistic variation are encapsulated in a style object. Like a shape object, a style object is a data structure that you manipulate with functions provided by QuickDraw GX. Each style object has a group of properties, and each style property represents a different stylistic variation.
  3951. Shapes and Styles
  3952.  
  3953. In general, a shape object is an object with a group of properties that describe a geometry; a style object is an object with a group of properties that affect how QuickDraw GX interprets a shape’s geometry during drawing.
  3954. Every QuickDraw GX shape object contains a reference to a style object. Figure 3-1 shows the properties of a style object. In this figure, the geometric properties—those that apply primarily to geometric shapes—are highlighted. These properties are discussed in this chapter. The other style properties are shown in grey. These include
  3955. n    the typographic style properties (those that apply primarily to typographic shapes), which are described in the chapter “Typographic Styles” in Inside Macintosh: QuickDraw GX Typography
  3956. n    the object-related style properties (owner count and tag list), which are described in the chapter “Style Objects” of Inside Macintosh: QuickDraw GX Objects
  3957. Figure 3-1    Style object with geometric properties highlighted 
  3958.  
  3959. As Figure 3-2 depicts, a single style object may be shared by multiple shape objects.
  3960. Figure 3-2    Shared style objects
  3961.  
  3962. A geometric shape and a typographic shape can reference the same style object. The geometric shape uses the geometric style properties, which are described in this chapter, while the typographic shape uses the typographic style properties, which are described in the chapter “Typographic Styles” in Inside Macintosh: QuickDraw GX Typography.
  3963. Figure 3-3    A geometric shape and a typographic shape sharing a style 
  3964.  
  3965. QuickDraw GX typically handles style sharing for you. The section “Default Style Objects” on page 3-13 and the section “Associating Styles With Shapes” on page 3-36 describe the default style sharing behavior implemented by QuickDraw GX and how you can override this behavior.
  3966. As with all QuickDraw GX objects, a style object has an owner count, which reflects the number of existing references to the style object. When a new reference to a style object is created, the owner count of the style object is incremented; when a reference to a style object goes away, the owner count of the style object is decremented. When a style object has an owner count of 0, QuickDraw GX can free the memory used by the style object.
  3967. References to style objects typically include those contained in shape objects and those contained in variables in your application. QuickDraw GX manages the owner counts corresponding to references in shape objects for you; you are responsible for managing the owner counts corresponding to variables in your application. The chapter “Introduction to QuickDraw GX Objects” in Inside Macintosh: QuickDraw GX Objects explains owner counts and owner count management in more detail.
  3968. Incorporating Stylistic Variations Into Shape Geometries
  3969.  
  3970. When you draw a shape, QuickDraw GX applies the information in the style object of the shape to the shape’s geometry. For example, style objects contain a pen width property, described in full later in this chapter. When you draw a line shape, QuickDraw GX draws the line with the width specified in the pen width property of the style object associated with the line shape. As drawn, the thick line looks like a filled polygon. However, even after drawing the line shape, the shape still contains a line geometry.
  3971. QuickDraw GX provides a mechanism for incorporating the stylisticvariations contained in a style object directly intothe geometry of a shape object. This mechanism is the GXPrimitiveShape function, which is described in full in the next chapter, “Geometric Operations.”
  3972. If you make changes to a shape’s style object and then call the GXPrimitiveShape function, QuickDraw GX changes the shape’s shape type, shape fill, and shape geometry to incorporate the new stylistic variations. Basically, the same process that happens when drawing the shape happens directly to the shape’s geometry.
  3973. For example, Figure 3-4 shows a line shape. If you alter the style of this line shape to include a pen width of 10, the line shape effectively becomes a filledpolygon shape.
  3974. If you were to apply the GXPrimitiveShape function to this thick line shape, the GXPrimitiveShape function would change the shape type to gxPolygonType, the shape fill to gxEvenOddFill, and the shape geometry to a list of the four geometric points that define the polygon, as shown in Figure 3-4.
  3975. Another example, the result of applying the GXPrimitiveShape function to a framed rectangle with a thick pen width is shown in Figure 3-5. In this case, the result of the GXPrimitiveShape function is a filled polygon shape with two contours: an inside contour and an outside contour.
  3976. Figure 3-4    Effects of the GXPrimitiveShape function
  3977.  
  3978. Figure 3-5    Another example of primitive shapes
  3979.  
  3980. Notice that the GXPrimitveShape function does not affect the style object of the shape: it merely incorporates the existing style information into the geometry of the shape.
  3981. The result of calling the GXPrimitveShape function is called a primitive shape, or a shape in its primitive form. Primitive shapes include
  3982. n    empty shapes and full shapes, which are described in the Chapter 3, “Geometric Shapes”
  3983. n    filled rectangle, polygon, and path shapes, which are also described in the Chapter 3, “Geometric Shapes”
  3984. n    hairline framed shapes, which are described on page 3-17
  3985. n    glyph shapes, which are described in Inside Macintosh: QuickDraw GX Typography
  3986. QuickDraw GX uses primitive shapes for caps, joins, dashes, and patterns, which are discussed throughout the rest of this chapter, and for clip shapes, which are discussed in the chapter “Transform Objects” of Inside Macintosh: QuickDraw GX Objects.
  3987. Style Properties
  3988.  
  3989. Like most QuickDraw GX objects, each style object has an owner count and a list of tags. These properties are described in detail in the chapter “Introduction to QuickDraw GX Objects” in Inside Macintosh: QuickDraw GX Objects.
  3990. In addition to the owner count and the tag list, each style object contains properties that primarily affect the drawing of geometric shapes and properties that primarily affect the drawing of typographic shapes.
  3991. The style properties that primarily affect geometric shapes include
  3992. n    Curve error. This property specifies the allowable amount of error when QuickDraw GX converts a path shape into a polygon shape. It also specifies how far apart geometric points must be for QuickDraw GX to consider them separate points when simplifying or reducing a shape. 
  3993. n    Pen width. This property specifies the width of the pen QuickDraw GX uses to draw the contours of a shape. 
  3994. n    Style attributes. This property is a group of flags that allow you to specify how QuickDraw GX places the pen with respect to a shape’s geometry and whether the shape should be constrained to a grid when drawn. 
  3995. n    Caps. This property specifies what QuickDraw GX should draw at the start and the end of a shape’s contours. QuickDraw GX allows you to use any geometric shape (for example, a polygon shaped like an arrow head) as a start cap or end cap.
  3996. n    Join. This property specifies what QuickDraw GX should draw at the corners of a shape’s geometry. QuickDraw GX provides two standard join types (one for round corners and one for sharp corners), although QuickDraw GX allows you to specify any geometric shape as a join.
  3997. n    Dash. This property specifies how QuickDraw GX should dash the contours of a shape. As with caps and joins, you can specify any geometric shape to dash the contours of another shape. However, you can also dash a shape with glyphs, which gives the affect of fitting text to a shape’s contours.
  3998. n    Pattern. This property specifies how QuickDraw GX should fill the geometry of a shape. You can use geometric shapes, glyphs shapes, or bitmap shapes as patterns.
  3999. The sections “Curve Error” on page 3-14, “The Geometric Pen” on page 3-15, “Style Attributes” on page 3-17, and “Caps, Joins, Dashes and Patterns” on page 3-22 discuss these style properties in more detail.
  4000. The typographic style properties, which include font, font size, text face, and so on are described in Inside Macintosh: QuickDraw GX Typography.
  4001. Default Style Objects
  4002.  
  4003. When you call the GXNewStyle function, which is described in the chapter “Style Objects” in Inside Macintosh: QuickDraw GX Objects, QuickDraw GX creates and returns a new style object. All of the new style object’s properties are set to standard initial values. Once you have created a new style object, you can change the values of its properties, but you cannot change the behavior of the GXNewStyle function itself; it always returns a style object with these values for the geometric style properties:
  4004. n    owner count: 1
  4005. n    tag list: nil
  4006. n    style attributes: gxNoAttributes
  4007. n    curve error: 0
  4008. n    pen width: 0
  4009. n    cap attributes: gxNoAttributes
  4010. n    start cap: nil
  4011. n    end cap: nil
  4012. n    join attributes: gxNoAttributes
  4013. n    join: nil
  4014. n    join miter: gxSharpJoin
  4015. n    dash attributes: gxNoAttributes
  4016. n    dash: nil
  4017. n    dash advance: 0
  4018. n    dash phase: 0
  4019. n    dash scale: fix1
  4020. n    pattern attributes: gxNoAttributes
  4021. n    pattern: nil
  4022. n    pattern grid: (0.0,0.0), (0.0,0.0)
  4023. The “Typographic Shapes and Styles” chapter of Inside Macintosh: QuickDraw GX Typography discusses the default style values for the typographic style properties.
  4024. Although you cannot change the behavior of the GXNewStyle function, QuickDraw GX provides another method for creating new style objects—a method that you can modify. When you create a new shape with the GXNewShape function, QuickDraw GX returns a copy of the default shape of the requested type. Since you can change the default shapes, you can also change the style objects that they reference. 
  4025. Initially, all of the default shape objects reference the same style object. Whenever you create a new shape, it, too, references this style object. There are two ways in which you can change the style object associated with a new shape:
  4026. n    You can call a function such as GXSetShapePen, which makes a copy of the style object specifically for your new shape before changing its pen width.
  4027. n    You can obtain a reference to your new shape’s style object by calling the GXGetShapeStyle function, and then you can call a function such as GXSetStylePen, which does not make a copy of the style object. Instead, it affects the style object directly, which, in effect, changes the default style for all the default shapes.
  4028. By calling functions such as GXSetShapePen on each of the default shapes, you can create a different style object for each default shape. See the chapter“Shape Objects” of Inside Macintosh: QuickDraw GX Objects for more information about default shapes.
  4029. Curve Error
  4030.  
  4031. Curve error is the only geometric style property that doesn’t affect the drawing of a shape; instead, it affects the geometric points of the shape’s geometry when performing geometric operations, shape type conversions, and shape simplifications. The curve error property determines how far away two points must be for QuickDraw GX to consider them separate points in these cases:
  4032. n    Geometric operations. QuickDraw GX guarantees that the results of the geometric operations described in the chapter “Geometric Operations” in this book, such as GXIntersectShape or GXUnionShapehave no two points closer than the value of the curve error of the target shape.
  4033. n    Insetting shapes. A special case of geometric operation, the GXInsetShape function, which is decsribed in the chapter “Geometric Operations” in this book, can produce results with an unusually large number of geometric points. Because the inset of a quadratic Bézier curve is not a quadratic Bézier curve itself, multiple insets of tight curve shapes can cause the number of geometric points to grow dramatically. As with the other geometric operations, the result of the GXInsetShape function has no two consecutive points closer than the value of the curve error of the target shape.
  4034. n    Path to polygon conversions. The curve error also determines the maximum error when converting a path shape to a polygon (for example, with the code GXSetShapeType(aPathShape, gxPolygonType)). The distance between the original path and the resulting polygon is always less than the value of the curve error. If the curve error is 0, QuickDraw GX performs the path to polygon conversion simply by removing all off-curve control points, which gives a fairly rough approximation.
  4035. n    Shape simplifications. The functions GXReduceShape and GXSimplifyShape, which are described in more detail the chapter “Geometric Operations” in this book, perform a number of simplifications on shapes (for example, removing geometric points unnecessary to the geometry and unwinding crossed contours). In addition to their other simplifications, these functions remove all consecutive (on-curve) geometric points within a distance of less than the curve error.
  4036. n    Style integration. The GXPrimitiveShape function, which integrates the stylistic variations indicated by a shape’s style into the shape’s geometry, also considers curve error. The resulting shape geometry has no two geometric points within a distance of less than the curve error.
  4037. The sections “Converting Paths to Polygons” on page 3-43 and “Using Curve Error When Reducing Shapes” on page 3-46 give examples of using curve error, and the section “Getting and Setting Curve Error” on page 3-107 describes the functions you can use to manipulate this style property.
  4038. The Geometric Pen
  4039.  
  4040. The contours of framed geometric shapes are drawn with the QuickDraw GX geometric pen. You can specify the width of this pen using the pen width property of the style object, and you can specify where to place the pen relative to the contours of a shape using the style attributes, described in “Style Attributes” beginning on page 3-17.
  4041. Conceptually, the QuickDraw GX geometric pen is a line that QuickDraw GX drags along the contours of the shape being drawn—always keeping it perpendicular to the contours. In effect, the geometric pen turns a framed geometry into a filled one. For example, a line shape, which is always framed, becomes the equivalent of a filled polygon after QuickDraw GX applies the geometric pen.
  4042. Figure 3-4 shows the effect of the geometric pen. This figure shows two geometries— a line geometry and a curve geometry—and how QuickDraw GX draws them with a pen width of 15.
  4043. Figure 3-6    The QuickDraw GX geometric pen
  4044.  
  4045. Notice that the ends of the thick line contour and the thick curve contour in Figure 3-4 are perpendicular to the direction of the contours themselves.
  4046. The pen width property of the style object allows you to specify the width of the geometric pen. Figure 3-7 shows the effect of different pen widths on a semicircular path shape.
  4047. Figure 3-7    Differing pen widths
  4048.  
  4049. Setting a value of 0 for the pen width property has special meaning. Instead of indicating an infinitely thin pen, it indicates that a shape’s contours should be drawn using hairlines—the thinnest line renderable on the device to which the shape is drawn. A hairline is always one pixel wide and is always centered about the shape’s geometry. 
  4050. One important use of hairlines is to make point shapes visible. QuickDraw GX draws point shapes under only two conditions: if the pen width is 0, indicating a hairline point, in which case exactly one pixel is drawn, or if the point has a start cap, which is described in “Caps” on page 3-23.
  4051. When drawing a hairline, QuickDraw GX uses this algorithm to determine which pixels to include:
  4052. n    If the contour being drawn is more vertical than horizontal, QuickDraw GX includes a pixel if the contour crosses the horizontal center line of the pixel.
  4053. n    If the contour being drawn is more horizontal than vertical, QuickDraw GX includes a pixel if the contour crosses the vertical center line of the pixel.
  4054. Figure 3-8 depicts this algorithm.
  4055. Figure 3-8    Pixels included in a hairline 
  4056.  
  4057. In extreme cases, this algorithm can cause no pixels to draw, as shown in Figure 3-9.
  4058. Figure 3-9    A geometry with no hairline 
  4059.  
  4060. The section “Manipulating Pen Width and Placement” on page 3-48 gives an example of the pen width property, and the section “Getting and Setting the Pen Width” on page 3-112 describes the functions you can use to manipulate it.
  4061. Style Attributes
  4062.  
  4063. The style attributes property of a style object contains six attributes that affect the drawing of a shape. Four of these attributes affect how QuickDraw GX places the geometric pen relative to the contours of a shape:
  4064. n    The center-frame style attribute indicates that the QuickDraw GX should center the geometric pen along the shape’s contours.
  4065. n    The inside-frame style attribute indicates that QuickDraw GX should position the pen along the inside of a shape’s contours.
  4066. n    The outside-frame style attribute indicates that QuickDraw GX should position the pen along the outside of shape’s contours.
  4067. n    The auto-inset style attribute affects the definition of the inside and outside of a contour.
  4068. These four attributes are discussed in the next section, “Pen Placement.”
  4069. There are also two style attributes that determine whether the geometric points of a shape are constrained to a grid when the shape is drawn:
  4070. n    The source-grid style attribute constrains the geometric points of a shape to integer values before applying the shape’s style and transform information.
  4071. n    The device-grid style attribute constrains the geometric points of a shape to integer pixel positions after applying the shapes style and transform information.
  4072. These two attributes are discussed in the sectin “Grids” beginning on page 3-21.
  4073. Pen Placement
  4074.  
  4075. You can use the gxCenterFrameStyle, gxInsideFrameStyle, and gxOutsideFrameStyle style attributes to specify where QuickDraw GX should position the pen with respect to the shape’s geometry.
  4076. Figure 3-10 shows the results of these style attributes. Notice that QuickDraw GX considers contour direction when determining which side of a contour is the inside: the right side of the contour is the inside, while the left side of the contour is the outside.
  4077. Figure 3-10    Pen placement
  4078.  
  4079. QuickDraw GX also provides the gxAutoInsetStyle style attribute, which allows you to specify that QuickDraw GX should ignore contour direction when determining which side of a contour is the inside. When you set this style attribute, QuickDraw GX determines the true inside of a contour, rather than using the right side as the inside. Figure 3-11 shows the effect of setting auto-inset style attribute for the shapes depicted in Figure 3-10.
  4080. Figure 3-11    Effect of the auto-inset style attribute
  4081.  
  4082. When a contour crosses over itself, the results of setting the gxAutoInsetStyle style attribute are unpredictable, as the contour has no true inside (or, actually, has mulitple true insides). For the figure-eight shape in Figure 3-12, setting the gxAutoInsetStyle and the gxInsideFrameStyle style attributes could lead to one of two results.
  4083. Figure 3-12    Effect of the auto-inset style attribute for a crossed contour
  4084.  
  4085. To ensure that setting the auto-inset style attribute behaves as you would expect, you need to call the GXSimplifyShape function, which is described in the chapter “Geometric Operations”in this book. This function redefines the shape’s geometry to eliminate crossed contours, as shown in Figure 3-13.
  4086. Figure 3-13    Eliminating crossed contours
  4087.  
  4088. The section“Manipulating Pen Width and Placement” on page 3-48 gives an example of pen placement. The section “Style Attributes” on page 3-92 discusses style attributes, and the section “Getting and Setting Style Attributes” on page 3-102 describes the functions you can use to manipulate them.
  4089. Grids
  4090.  
  4091. From the initial geometry specification to the final image rendering, each QuickDraw GX shape exists in a number of different coordinate spaces. You describe a shape’s geometry in geometery space, the style and transform modifications happen in local space, the shape then exists in one or more view ports’ global spaces, and the shape is finally rendered in the pixels of a view device’s device space.
  4092. In each of these coordinate spaces, QuickDraw GX allows fractional coordinate values. When you specify points in a shape’s geometry, you are not limited to integer values, such as (1, 1) or (–10, 10). Instead, you can specify that shapes’ geometric points fall between integral positions in the geometry spaces’ coordinate grid, for example (0.5, 0.5). During each transformation of the shape from geometry to rendering, QuickDraw GX maintains fractional coordinate values.
  4093. The style attributes property of a style object contains two flags that allow you to suppress fractional coordinate values—that is, these flags allow you to constrain a shape’s geometric points to integer coordinate values in the different coordinate systems.
  4094. The gxSourceGridStyle attribute indicates that QuickDraw GX should constrain the shape’s geoemtric points to integral positions on the local space grid, before making the style and transform modifications.
  4095. The gxDeviceGridStyle attribute indicates that QuickDraw GX should constrain the shape’s geometric points to integral positions (that is, pixel positions) on the device space grid, after making style, transform, and view port modifications.
  4096. Note
  4097. These style attributes only affect a shape while it is being drawn. They do not affect the geometric points you specify in the original shape geometry.u
  4098. To constrain a shape to integral positions on a coordinate space’s grid, QuickDraw GX moves the entire shape (that is, all the shape’s geometric points) so that the shape’s first geometric point lies on the nearest grid position, and then moves each remaining geometric point to the nearest grid position.
  4099. Figure 3-14 depicts the grid-constraining algorithm.
  4100. Figure 3-14    Constraining Shapes to Grids
  4101.  
  4102. The sections “Constraining Shape Geometries to Grids” on page 3-39 and “Constraining Shapes to Device Grids” on page 3-41 give examples of the grid-constraining style attributes. The section “Style Attributes” on page 3-92 describes the style attributes data structures and the section “Getting and Setting Style Attributes” on page 3-102 describes the functions you can use to manipulate them.
  4103. Caps, Joins, Dashes and Patterns
  4104.  
  4105. The cap, join, dash, and pattern properties of the style object allow you to change the way QuickDraw GX draws the contours of a shape. The cap and join properties allow you place arbitrary shapes on the geometric points of a shape’s contours. For example, you can place arrow heads at the ends of a line, or you can put rounded edges at the corners of a rectangle. The dash property allows you to dash the contours of one shape with another shape. For example, you could dash a line with a circular path shape to get a dotted line.
  4106. The pattern property allows you to fill a shape (or the frame of a shape drawn with a thick pen width) with a repeated pattern of another shape. For example, you could fill a large square shape with a pattern of small squares to get a checkerboard.
  4107. Figure 3-15 shows some of the stylistic variations possible with caps, joins, dashes, and patterms.
  4108. Figure 3-15    Caps, Joins, Dashes, and Patterns
  4109.  
  4110. IMPORTANT
  4111. There is one important rule that applies to all four of these properties: Cap shapes, join shapes, dash shapes, and pattern shapes must all be in their primitive form. When QuickDraw GX uses a cap, join, dash, or pattern shape, it ignores the stylistic variations of that shape. If you want a cap, join, dash, or pattern shape to have stylistic variations itself, you must first incorporate those stylistic variations into the shape using the GXPrimitiveShape function.s
  4112. As an example, specifying a line shape with a thick pen (like the one in Figure 3-4) as a cap, join, dash, or pattern shape results in an error, since the shape is not in its primitive form. However, if you use the GXPrimitiveShape function, you can convert the line to a filled polygon, which is a perfectly acceptable cap, join, dash, or pattern shape.
  4113. As another example, a polygon with 0 contours is not an acceptable cap, join, dash, or pattern shape, as it is not in its primitive form. Similarly, any shape with the gxNoFill shape fill is not its primitive form. However, the empty shape, which is in its primitive form, is an acceptable cap, join, dash, or pattern shape. You can find more information about polygon shapes, polygon contours, and empty shapes in Chapter 2, “Geometric Shapes,” in this book.
  4114. You can always be sure your cap, join, dash, or pattern shape is in the correct form by calling the GXPrimitiveShape function, which is described in Chapter 4, “Geometric Operations,” before setting the corresponding style property.
  4115. As for typographic shapes, text and layout shapes are not in their primitive form, but glyph shapes are acceptable as cap, join, dash, and pattern shapes so long as they have no text face or tags and are not capped, joined, dashed, or patterned themselves. For more information, see Inside Macintosh: QuickDraw GX Typography.
  4116. You may use bitmap shapes as patterns, but not as caps, joins, or dashes, and you may not use picture shapes for caps, joins, dashes, or patterns.
  4117. The next few sections describe caps, joins, dashes, and patterns in more detail. 
  4118. Caps 
  4119.  
  4120. QuickDraw GX allows you to specify what to draw at the start and at the end of a shape’s contours. In particular, you may specify a start cap for any point shape, and you may specify a start cap and an end cap for any line, curve, polygon, or path shape that has open-frame shape fill.
  4121. In fact,  the only way to draw a point shape is to specify a start cap for it (unless it’s style object has a pen width property with a value of 0, in which case QuickDraw GX draws the point shape as a single pixel).
  4122. QuickDraw GX uses the cap property of a shape’s style object to store information about the start cap and end cap of the shape. 
  4123. Figure 3-16 shows how QuickDraw GX adds a cap to a contour by centering the cap shape at the end of the contour, scaling the cap shape by the pen width, and rotating the cap shape to match the slope of the contour.
  4124. Figure 3-16        A capped shape
  4125.  
  4126. The cap property of a style object includes a cap attributes field, which allows you to specify level caps—caps that QuickDraw GX does not rotate to match the slope of the contour—as shown in Figure 3-16.
  4127. Figure 3-17        Level caps
  4128.  
  4129. You can create two standard cap types by specifying half a square or a semicircle for the start cap or end cap shape, as shown in Figure 3-18.
  4130. Figure 3-18            Standard cap shapes
  4131.  
  4132. The sections “Adding Caps to a Shape” on page 3-53 and “Adding Standard Caps to a Shape” on page 3-56 give examples of the cap property, the section “Cap Record Structure” on page 3-94 describes the data structures used to store information about caps, and the section “Getting and Setting Start Caps and End Caps” on page 3-116 describes the functions you can use to manipulate caps.
  4133. Joins
  4134.  
  4135. QuickDraw GX allows you to specify a join shape to be drawn at the corners of another shape’s contours. In particular, you may specify a join shape for any rectangle, polygon, or path shape that has an open-frame shape fill or a closed-frame shape fill. 
  4136. n    For shapes with the closed-frame shape fill, QuickDraw GX draws the specified join shape at every on-curve geometric point of each contour.
  4137. n    For shapes with the open-fram shape fill, QuickDraw GX draws the specified join shape at every on-curve geoemtric point between the first point and the last point of each contour.
  4138. Figure 3-16 shows how QuickDraw GX adds a join to a contour by centering the join shape on the on-curve geometric points, scaling the join shape by the pen width, and rotating the join shape to match the mid-angle of the two line segments that make up the corner.
  4139. Figure 3-19        A joined shape
  4140.  
  4141. The join property of a style object includes a join attributes field, which allows you to specify level joins—joins that QuickDraw GX does not rotate to match the slope of the contour—as shown in Figure 3-16.
  4142. Figure 3-20        Level joins
  4143.  
  4144. You can also use the join attributes to specify two types of standard joins—sharp joins and curve joins, as shown in Figure 3-18.
  4145. Figure 3-21            Standard joins 
  4146.  
  4147. For sharp joins, QuickDraw GX allows you to specify a miter—the maximum distance between the actual corner of a shape’s geometry and the corner as drawn, as shown in Figure 3-22.
  4148. Figure 3-22    Sharp join with miter
  4149.  
  4150. The sections “Adding Joins to a Shape” on page 3-58 and “Adding Standard Joins to a Shape” on page 3-61 give examples of the join property, the section “Join Record Structure” on page 3-95 describes the data structures used to store information about joins, and the section “Getting and Setting Joins” on page 3-121 describes the functions you can use to manipulate them.
  4151. Dashes 
  4152.  
  4153. With QuickDraw GX, you can specify that framed shapes should be drawn with dashed, instead of solid, contours. In particular, you may specify a dash for any line, curve, rectangle, polygon, or path shape that has an open-frame shape fill or a closed-frame  shape fill. 
  4154. QuickDraw GX uses the dash property of a shape’s style object to store information about how to dash the shape. 
  4155. Figure 3-16 shows how QuickDraw GX dashes a contour by placing copies of the dash shape along the contour at regular intervals, and rotating the dash shape to match the slope of the contour.
  4156. Figure 3-23        A dashed shape
  4157.  
  4158. When drawing a dashed shape, QuickDraw GX automatically scales the dashe shape by the pen width of the dashed shape. However, unlike cap and joins, QuickDraw GX scales dashes only perpendicularly to the dashed contour.
  4159. For example, if the height of the dash shape is 1.0, then QuickDraw GX draws the dashes with a height equal to the dashed shape’s pen width. If the height of the dash shape is 2.0, then QuickDraw GX draws the dashes with a height equal to twice the dashed shape’s pen width.
  4160. Figure 3-24 shows the effect of different pen widths on the same dash shape. In this example, the dash shape has height of 1.0 (its y-coordinates span from -0.5 to 0.5). The shape being dashed is a curve, first shown with a pen width of 10 and then with a pen width of 20.
  4161. Figure 3-24                Scaling a dash shape
  4162.  
  4163. Note
  4164. Glyph shapes are an exception to this scaling rule. If the dash shape is a glyph shape, QuickDraw GX does not scale the dashes (which in this case would be glyphs) to the dashed shape’s pen width.u
  4165. Notice that the position of a dash shape in the coordinates of its geometry space is significant. For example, if the y-coordinates of the geometry of a dash shape span from 1.0 to 2.0, then QuickDraw GX draws the dashes at a distance of one pen width away from the dashed contour. If the lowest y-coordinate of a dash shape is 2.0, then QuickDraw GX draws the dashes at a distance of two pen widths away from the contour. 
  4166. Since the dash shape is scaled up by the pen width of the dashed shape, QuickDraw GX provides a way for you to scale the dash down, as well, by providing a scaling factor, called the dash scale, in one of the fields of the dash record structrure. QuickDraw GX scales the dash (perpendicularly to the dashed contour) down by the value you provide in this field.
  4167. If the y-coordinates of the geometry of a dash shape are large enough and the scaling factor you provided in the dash structure is small enough, the dashes may exceed the pen width of the dashed shape. QuickDraw GX provides the clip-dash dash attribute to indicate that QuickDraw GX should clip the dashes to the pen width, as illustrated in Figure 3-25.
  4168. Figure 3-25    Effect of the clip-dash dash attribute
  4169.  
  4170. Setting the clip-dash dash attribute causes some intricate interactions among dashes, caps, joins, and patterms. See “Interactions Between Caps, Joins, Dashes, and Patterns” on page 3-33 for more information.
  4171. QuickDraw GX also allows you to control how far apart the dashes appear from one another, which is called the dash advance, and how far into the dash shape the dashing should start, which is called the dash phase.
  4172. The dash advance is the distance between the start of one dash shape and the start of the next dash shape along the contour. The dash phase indicates where the first dash should fall on a contour; it is a percentage of the dash advance. 
  4173. When a dash shape has multiple contours, it is possible for the dashes not to fall on the contours of the dashed shape. For this situation, QuickDraw GX provides the break-dash dash attribute, which indicates that each contour of the dash should be rotated and placed separately on the dashed shape’s contours. Figure 3-26 depicts the result of setting this dash attribute.
  4174. Figure 3-26    Effects of breaking a dash
  4175.  
  4176. Finally, QuickDraw GX provides one other dashing feature. When dashing hairline contours, you can set the bend-dash dash attribute, which indicates that QuickDraw GX should wrap the dash to fit the dashed contour exactly, as shown in Figure 3-27.
  4177. Figure 3-27    Effects of bending a dash
  4178.  
  4179. Remember that bending a dash works only when dashing hairline contours.
  4180. The following sections give examples of dashing:
  4181. n    “Dashing a Shape” on page 3-63
  4182. n    “Adjusting Dashes to Fit Contours” on page 3-67
  4183. n    “Insetting Dashes” on page 3-69
  4184. n    “Breaking and Bending Dashes” on page 3-71
  4185. n    “Wrapping Text” on page 3-75
  4186. n    “Determining Dash Positions” on page 3-77
  4187. The section “Dash Record Structure” on page 3-97 describes the data structures used to store and communicate information about dashes, and the section “Getting and Setting Dashes” on page 3-126 describes the functions you can use to manipulate the dash property.
  4188. Patterns
  4189.  
  4190. With QuickDraw GX, you can specify that certain shapes be filled with a pattern. For shapes with solid shape fills, QuickDraw GX fills the shape by repeating a pattern shape that you specify. 
  4191. You can also pattern framed shapes. For example, imagine a rectangle shape with a closed-frame shape fill and a pen width of 20. If you patterned this rectangle, QuickDraw GX would fill the frame of the rectangle with the pattern. See the section “Interactions Between Caps, Joins, Dashes, and Patterns” on page 3-33 for more intricate examples.
  4192. QuickDraw GX uses the pattern property of a shape’s style object to store information about how to pattern the shape. 
  4193. Figure 3-16 shows how QuickDraw GX patterns a shape by filling the shape with copies of another shape, called the pattern shape, placed according to a regular grid.
  4194. Figure 3-28        A patterned shape
  4195.  
  4196. QuickDraw GX allows you to specify not only the shape to use as the pattern shape, but also the grid on which to place the pattern, as shown in Figure 3-29.
  4197. Figure 3-29    Pattern grids
  4198.  
  4199. In addition, QuickDraw GX provides you with two pattern attributes: the port-align pattern attribute and the port-map pattern attribute. Setting the port-align pattern attribute allows you to specify that QuickDraw GX should align the pattern with the view device instead of the geometry of the patterned shape. Figure 3-30 shows the effect of setting this attribute.
  4200. Figure 3-30    Effects of the port-align pattern attribute
  4201.  
  4202. The port-map pattern attribute indicates that the pattern shape should not be affected by transformations to the patterned shape. For example, if you set this pattern attribute, scaling the patterned shape by a factor of 2 does not also scale the pattern shape by a factor of 2; instead, more of the pattern is shown. Figure 3-31 shows the effect of setting this attribute.
  4203. Figure 3-31    Effects of the port-map pattern attribute
  4204.  
  4205. The sections “Adding a Pattern to a Shape” on page 3-81 and “Determining Pattern Positions” on page 3-83 give examples of pattens. The section “Pattern Record Structure” on page 3-99 describes the data structures used to store information about patterns, and the section “Getting and Setting Patterns” on page 3-132 describes the functions you can use to manipulate patterns.
  4206. Interactions Between Caps, Joins, Dashes, and Patterns
  4207.  
  4208. The previous four sections show the results of adding a cap, a join, a dash, or a pattern to a QuickDraw GX shape. This section discusses how these stylistic variations interact when you add more than one of them at a time to the same shape.
  4209. In general, these elements interact differently in each of these three cases:
  4210. n    the shape does not have a dash but has one or more of the other three stylistic variations
  4211. n    the shape does have a dash but the clip-dash dash attribute is not set
  4212. n    the shape does have a dash and the clip-dash dash attribute is set
  4213. When a shape has a cap and a join, QuickDraw GX adds the caps to the beginnings and ends of the shape’s contours, and adds the joins to the other on-curve control points of the shape’s contours. If the shape also has a pattern, QuickDraw GX draws this pattern throughout the shape’s contours as well as the shape’s caps and joins, as shown in Figure 3-32.
  4214. Figure 3-32    A shape with a cap, join, and pattern
  4215.  
  4216. If a shape has a dash, but the clip-dash attribute is not set, QuickDraw GX ignores the caps and joins of the shape. However, if the shape has a pattern, QuickDraw GX does draw the pattern throughout the dashes, as shown in Figure 3-33
  4217. Figure 3-33    A shape with a dash and a pattern
  4218.  
  4219. Finally, if the shape has a dash and the clip-dash dash attribute is set, QuickDraw GX does not ignore the caps and joins. Instead, the cap shapes and the join shapes are added to the clip shape that QuickDraw GX uses to clip the dashes. Patterns are not allowed in this case. Figure 3-34 shows the interaction of a cap, join, and clipped dash.
  4220. Figure 3-34    A shape with a clipped dash and a cap and join
  4221.  
  4222. The section “Combining Caps, Joins, Dashes, and Patterns” on page 3-86 give examples of the interactions between caps, joins, dashes, and patterns.
  4223.  
  4224. Using Geometric Styles
  4225.  
  4226. This section shows you how to use styles to add stylistic variations to geometric shapes. In particular, this section show you how to
  4227. n    create a style object, alter its properties, and associate the style with a shape 
  4228. n    alter the properties of a style object already associated with a shape
  4229. n    constrain shapes to grids
  4230. n    use curve error when approximating paths with polygons and when reducing shapes
  4231. n    manipulate pen width and placement
  4232. n    add caps to a shape, including round and square caps
  4233. n    add joins to a shape, including standard round and sharp joins
  4234. n    dash a shape
  4235. n    adjust dashes to fit contours
  4236. n    bend and break dashes
  4237. n    wrap text by using glyphs as a dash shape
  4238. n    determine dash positions
  4239. n    pattern a shape and determine pattern positions
  4240. n    combine caps, joins, dashes, and patterns
  4241. Associating Styles With Shapes
  4242.  
  4243. QuickDraw GX provides you with two basic methods of altering stylistic information for your shapes:
  4244. n    using functions that operate on style objects directly
  4245. n    using functions that operate on style objects indirectly through shape objects
  4246. The first category of functions require you to provide a reference to a style object, which you can obtain by using the GXNewStyle function to create a new style object, or by using the GXGetShapeStyle function to obtain a reference to an existing style object. (The GXNewStyle and GXGetShapeStyle functions are described in Inside Macintosh: QuickDraw GX Objects.)
  4247. Once you have a reference to a style object, you can use this category of functions to manipulate the style’s properties; for example, you can use the GXSetStylePen function to change the pen width of the style.
  4248. If you obtained the reference to the style object using the GXGetShapeStyle function, then the style is already associated with a shape—in fact, it may be shared amongst many shapes. Modifications you make to the style’s properties will apply to all shapes that share the style.
  4249. However, if you created the style object using the GXNewStyle function, you must then associate the style with a shape for the style modifications to have any effect. You can associate a style with a shape using the GXSetShapeStyle function, as shown in Listing 3-1.
  4250. Listing 3-1    Adding style information by directly manipulating a style object
  4251.  
  4252. gxShape MakeThickPenStyle()
  4253. {
  4254.     gxShape         aRectangleShape;
  4255.     gxStyle        aThickPenStyle;
  4256.  
  4257.     gxRectangle     rectangleGeometry = {ff(50), ff(50), 
  4258.                                             ff(200), ff(200)};    
  4259.                                    
  4260.  
  4261.     aRectangleShape = GXNewRectangle(&rectangleGeometry);
  4262.     GXSetShapeFill(aRectangleShape, gxClosedFrameFill);
  4263.     
  4264.     aThickPenStyle = GXNewStyle();
  4265.     GXSetStylePen(aThickPenStyle, ff(30));
  4266.     
  4267.     GXSetShapeStyle(aRectangleShape, aThickPenStyle);
  4268.     GXDisposeStyle(aThickPenStyle);
  4269.     
  4270.     GXDrawShape(aRectangleShape);
  4271. }
  4272. The MakeThickPenStyle sample function creates a rectangle shape and sets its shape fill to the closed-frame shape fill, making it a framed rectangle. The sample function then creates a new style object using the GXNewStyle function, which creates a style object with properties set to the standard initialized values. The owner count of this style object is 1, corresponding to the reference contained in the aThickPenStyle variable. The sample function then alters the pen width of the new style using the GXSetStylePen function. 
  4273. To associate the style with the rectangle shape, the sample function calls the GXSetShapeStyle function. This function disposes of the style previously referenced by the rectangle shape, stores a reference to the new style in the rectangle shape object, and increments the style’s owner count—there are now two references to the style: one in the sample function’s local variable, and one in the rectangle shape.
  4274. Finally, the sample function disposes of the style, which indicates that the reference to the style stored in the local variable aThickPenStyle is no longer needed. QuickDraw GX decrements the owner count of the style, which becomes 1, corresponding to the reference contained in the rectangle shape.
  4275. Finally, the sample function draws the rectangle, which appears as in Figure 3-35.
  4276. Figure 3-35    Rectangle with thick pen
  4277.  
  4278. The second method of altering styles involves functions that operate on style objects indirectly through the shape objects that reference them.
  4279. When using this category of function, you need only provide a reference to the shape whose style information you want to change. QuickDraw GX finds the associated style object and alters the appropriate style property for you.
  4280. In fact, QuickDraw GX provides one further level of service with this category of functions. If the shape that you specify is sharing its style with other shapes, QuickDraw GX first makes a copy of the style object, associates the copy with the shape you specified, and then alters the appropriate property of the copy.
  4281. Listing 3-2 shows an alternate approach to creating the thick-framed rectangle from Listing 3-1. 
  4282. Listing 3-2    Manipulating style information indirectly
  4283.  
  4284. gxShape MakeThickRectangle()
  4285. {
  4286.     gxShape         aRectangleShape;
  4287.  
  4288.     gxRectangle     rectangleGeometry = {ff(50), ff(50), 
  4289.                                               ff(200), ff(200)};    
  4290.                                    
  4291.  
  4292.     aRectangleShape = GXNewRectangle(&rectangleGeometry);
  4293.     GXSetShapeFill(aRectangleShape, gxHollowFill);
  4294.     
  4295.     GXSetShapePen(aRectangleShape, ff(30));
  4296.     
  4297.     GXDrawShape(aRectangleShape);
  4298. }
  4299. As in Listing 3-1, this sample function creates a new framed rectangle shape. However, instead of creating a style object, altering the pen width property of the style object with the GXSetStylePen function, and associating the style with the rectangle shape, this sample function uses the GXSetShapePen function to accomplish those tasks in one step.
  4300. Since the rectangle shape is a new shape, it shares its style object with other shapes—the default rectangle shape at the very least. The GXSetShapePen function notices that the rectangle shape’s style is shared, so it makes a copy of this style, associates the copy with the rectangle shape, and alters the pen width property of this copy.
  4301. The result of this sample function looks exactly the same as the result of the previous sample function, as shown in Figure 3-35.
  4302. For simplicity, the rest of the sample functions in this chapter use the second method for altering style properties.
  4303. Constraining Shape Geometries to Grids
  4304.  
  4305. The source-grid style attribute (gxSourceGridStyle) allows you to specify that QuickDraw GX should constrain the coordinates of a shape’s geometry to integer positions before applying the shape’s style and transform. Setting this style attribute does not actually change the information stored in the shape’s geometry—instead, QuickDraw GX reinterprets the shape’s geometry when drawing the shape.
  4306. If a shape has no style or transform modifications, setting this style attribute has the effect of snapping the shape to 1/72 inch grid—an effect that is only visible on high-resolution devices. However, if the shape has style or transform modifications, setting this style attribute might have visible effects even on lower-resolution devices.
  4307. For example, you can use this style attribute in combination with a scaling transform to achieve the effect of constraining a shape to a grid much larger than 1/72 inch. The sample function in Listing 3-3 shows how to use this style attribute to constrain a shape to a half-inch grid.
  4308. Listing 3-3    Constraining a shape to a half-inch grid
  4309.  
  4310. gxShape ConstrainShapeToGrid(void)
  4311. {    
  4312.     gxMapping             scaleToHalfInches;
  4313.     long veeGeometry[] = {1, /* number of contours */
  4314.                                  3, /* number of points */
  4315.                                  fl(1.2), fl(1.1),
  4316.                                  fl(2.9), fl(2.8),
  4317.                                  fl(5.2), fl(.9)};
  4318.     gxShape aVeeShape;
  4319.  
  4320.     aVeeShape = GXNewPolygons((gxPolygons *) veeGeometry);
  4321.     GXSetShapeFill(aVeeShape, gxOpenFrameFill);
  4322.     GXSetShapePen(aVeeShape, fl(5.0 * (1.0/36.0)));
  4323.  
  4324.     GXResetMapping(scaleToHalfInches);
  4325.     GXScaleMapping(scaleToHalfInches, ff(36), ff(36), 
  4326.                        ff(0), ff(0));
  4327.      GXSetShapeMapping(aVeeShape, scaleToHalfInches);
  4328.  
  4329.     GXDrawShape(aVeeShape);
  4330. }
  4331. This sample function defines a small, irregular, V-shape geometry and scales the shape up by 36 points, or half an inch. The result of this sample function is shown in
  4332. Figure 3-36.
  4333. Figure 3-36    Scaled, but not constrained, V shape
  4334.  
  4335. Notice that before QuickDraw GX applies the mapping, the coordinates of the shape’s geometry represent points, whereas after QuickDraw GX applies the mapping, the coordinates of the shape’s geometry effectively represent half inches.
  4336. If you set the source-grid style attribute by adding this line of code to the sample function:
  4337. GXSetShapeStyleAttributes(aVeeShape, gxSourceGridStyle);
  4338. QuickDraw GX constrains the coordinates of the shape’s geometry to the nearest integer position before applying the mapping. Therefore, after the mapping, the shape’s geometric points lie on a half-inch grid, as shown in Figure 3-37.
  4339. Figure 3-37    Constrained V shape
  4340.  
  4341. The sample function in this section uses some concepts from other parts of QuickDraw GX. For more information about scaling, mappings, and transforms, see the chapter “Transform Objects” in Inside Macintosh: QuickDraw GX Objects.
  4342. For more information about the gxSourceGridStyle style attribute, see “Style Attributes” on page 3-92.
  4343. Constraining Shapes to Device Grids
  4344.  
  4345. QuickDraw GX also provides the device-grid style attribute (gxDeviceGridStyle), which allows you to constrain the geometric points of a shape to integer positions after the style, transform, and view modifications have been made.
  4346. This style attribute constrains the geometric points of a shape to the nearest integer pixel position on the device to which the shape is rendered. Unlike source-grid style attribute, the device-grid style attribute never drastically affects the position of the shape. However, QuickDraw GX does make minor modifications when drawing contours whose geometric points lie between pixels; you can use the device-grid style attribute to override these modifications, which typically produces better-looking results.
  4347. The sample function in Listing 3-4 creates a star-shaped polygon and rotates it 28 degrees, which causes its geometric points to lie between integer positions.
  4348. Listing 3-4    Creating a shape with fractional geometric point positions
  4349.  
  4350. gxShape ConstrainShapeToDeviceGrid(void)
  4351. {
  4352.     long        starGeometry[] = {    1, /* number of contours */
  4353.                                     9, /* number of points */
  4354.                                     ff(40), ff(40),
  4355.                                     ff(50), ff(20),
  4356.                                     ff(60), ff(40),
  4357.                                     ff(80), ff(50),
  4358.                                     ff(60), ff(60),    
  4359.                                     ff(50), ff(80),
  4360.                                     ff(40), ff(60),
  4361.                                     ff(40), ff(40),
  4362.                                   };    
  4363.     gxShape         aStar;
  4364.  
  4365.     aStar = GXNewPolygons((gxPolygons *) starGeometry);
  4366.     GXSetShapeFill(aStar, gxOpenFrameFill);
  4367.  
  4368.     RotateShapeAboutCenter(aStar, ff(28));
  4369.     GXDrawShape(aStar);
  4370. }
  4371. Because the geometric points of the rotated star do not lie on integer positions, QuickDraw GX does not draw the contours of the star with the most visually appealing lines; instead, it makes minor adjustments to reflect the fractional part of the geometric point coordinates.
  4372. Figure 3-38    Rotated star not constrained to device grid (magnified 200 percent)
  4373.  
  4374. If you constrain the star shape to the device grid by adding this line of code to the sample function:
  4375. GXSetShapeStyleAttributes(aStar, gxDeviceGridStyle);
  4376. QuickDraw GX constrains the shape’s geometric points to the device grid before choosing the pixels to represent the shape’s contours, which creates better-looking lines, as shown in Figure 3-39.
  4377. Figure 3-39    Rotated star constrained to device grid (magnified 200 percent)
  4378.  
  4379. The sample function in this section uses some concepts from other parts of QuickDraw GX. For more information about rotating, mappings, and transforms, see the chapter “Transform Objects” in Inside Macintosh: QuickDraw GX Objects.
  4380. For more information about the gxDeviceGridStyle style attribute, see “Style Attributes” on page 3-92. For more information about fractional coordinates, see Chapter 1, “Graphics Shapes.”
  4381. Converting Paths to Polygons
  4382.  
  4383. You can use the curve error property of the style object in a variety of situations— for example, when approximating a path shape (which includes curves) with a polygons shape (which includes only straight lines).
  4384. The GXSetShapeType function allows you to convert a shape from one shape type to another. When you convert a path shape that contains curves to a polygon shape, QuickDraw GX uses the curve error of the shape’s style to determine how close to make the polygon approximation. The distance between the polygon and the original path is never greater than the number of grid points (1/72 inch units) specified by the curve error.
  4385. Listing 3-5 shows a sample function that creates a circular path shape, sets its curve error to 1, and converts it to a polygon shape.
  4386. Listing 3-5    Converting a circle to a polygon
  4387.  
  4388. gxShape ConvertCircleToPolygon()
  4389. {
  4390.     gxRectangle             circleBounds = {ff(50), ff(50), 
  4391.                                         ff(200), ff(200)};
  4392.  
  4393.     gxShape              aCircle;
  4394.  
  4395.  
  4396.     aCircle = NewArc(&circleBounds, ff(0), ff(360), false);
  4397.     GXSetShapeFill(aCircle, gxClosedFrameFill);
  4398.  
  4399.     GXSetShapeCurveError(aCircle, ff(1));
  4400.     GXSetShapeType(aCircle, gxPolygonType);
  4401.     GXDrawShape(aCircle);
  4402. }
  4403. Since the curve error is 1 in this example, the resulting polygon is never more than 1 grid point away from the original circle, which makes for an accurate approximation, as shown in Figure 3-40.
  4404. Figure 3-40    Accurate polygon approximation of a circle
  4405.  
  4406. Increasing the curve error decreases the accuracy of the approximation. Setting the curve error to 5 in this example creates the polygon shown in Figure 3-41, which has only 16 sides.
  4407. Figure 3-41    Less accurate polygon approximation of a circle
  4408.  
  4409. If you increase the curve error to 10, the octagon shown in Figure 3-42 results.
  4410. Figure 3-42    Highly inaccurate polygon approximation of a circle
  4411.  
  4412. Although decreasing the curve error leads to more accurate approximations in general, a curve error of 0 is a special case. A curve error of 0 indicates that QuickDraw GX should not approximate the path at all. Instead, QuickDraw GX simply removes all off-curve control points, leaving a polygon made up of the on-curve geometric points of the initial path. 
  4413. In Listing 3-5, the circular path returned by the NewArc library routine contains eight off-curve control points, which imply eight on-curve geometric points midway between each pair of off-curve control points. A curve error of 0 results in a polygon containing these eight on-curve points, as shown in Figure 3-43.
  4414. Figure 3-43    Polygon resulting from a curve error of 0
  4415.  
  4416. For more information about paths, polygons, and on-curve and off-curve geometric points, see Chapter 3, “Geometric Shapes.”
  4417. For more information about curve error and the functions you can use to manipulate it, see “Getting and Setting Curve Error” on page 3-107. 
  4418. Using Curve Error When Reducing Shapes
  4419.  
  4420. You can also use curve error to eliminate excess detail in complicated shapes. When you call the GXReduceShape or GXSimplifyShape functions, QuickDraw GX averages points within a curve error of each other. 
  4421. You can use this feature to smooth a complicated contour, such as the wavy line create in Listing 3-6.
  4422. Listing 3-6    Creating a complicated contour
  4423.  
  4424. gxShape FlattenWavyLine()
  4425. {
  4426.     gxShape         aWave;
  4427.  
  4428.     long        wavyGeometry[] = {    1, /* number of contours */
  4429.                                     13, /* number of points */
  4430.                                     0x2AA00000,
  4431.                                     ff(80), ff(100),                        /* on  */
  4432.                                     ff(110), ff(100),                        /* on  */
  4433.                                     ff(113), ff(91),                         /* off */
  4434.                                     ff(118), ff(103),                        /* on  */
  4435.                                     ff(123), ff(85),                        /* off */
  4436.                                     ff(128), ff(100),     /* on  */
  4437.                                     ff(133), ff(112),     /* off */
  4438.                                     ff(135), ff(97),                         /* on  */
  4439.                                     ff(141), ff(106),     /* off */
  4440.                                     ff(145), ff(94),                         /* on  */
  4441.                                     ff(150), ff(109),     /* off */
  4442.                                     ff(153), ff(100),     /* on  */
  4443.                                     ff(183), ff(100)                        /* on  */
  4444.                                 };
  4445.  
  4446.     aWave = GXNewPaths((gxPaths *) wavyGeometry);
  4447.     GXSetShapeFill(aWave, gxOpenFrameFill);
  4448.  
  4449.     GXDrawShape(aWave);
  4450. }
  4451. The shape created by this sample function is shown in Figure 3-44.
  4452. Figure 3-44    Wavy line
  4453.  
  4454. If you add the following lines of code to this sample function:
  4455. GXSetShapeCurveError(aWave, ff(10));
  4456. GXReduceShape(aWave, 0);
  4457. the resulting shape has a slightly smoother appearance because QuickDraw GX averages geometric points within the specified distance (a distance of 10 grid points). Figure 3-45 shows the resulting shape.
  4458. Figure 3-45    Wavy line somewhat smoothed by curve error of 10
  4459.  
  4460. Increasing the curve error increases the number of points that QuickDraw GX averages. A curve error of 15 results in the shape shown in Figure 3-46.
  4461. Figure 3-46    Wavy line smoothed by curve error of 15
  4462.  
  4463. A curve error of 20 results in a completely straight line—all of the points between the start point and the end point of the contour have been averaged out.
  4464. Figure 3-47    Wavy line completely straightened by curve error of 20
  4465.  
  4466. Note
  4467. When QuickDraw GX reduces a shape, it does not ignore the first and last points of the contour. If these points had been close enough to the other points in this example, they, too, would have been averaged, and the entire shape would have become a point.u
  4468. For more information about curve error and the functions you can use to manipulate it, see “Getting and Setting Curve Error” on page 3-107. 
  4469. Manipulating Pen Width and Placement
  4470.  
  4471. The pen width property of a style object determines the width with which QuickDraw GX draws a shape’s contours, and three of the style attributes (gxCenterFrameStyle, gxInsideFrameStyle, and gxOutsideFrameStyle) determine where QuickDraw GX places the pen in relation to a shape’s contours.
  4472. Since contour direction and crossed contours affect pen placement, the examples in this section use a path shape shaped like a figure eight, as defined in Listing 3-7.
  4473. Listing 3-7    Defining a figure eight
  4474.  
  4475. gxShape CreateFigureEight()
  4476. {
  4477.     gxShape     aPathShape;
  4478.  
  4479.     long     figureEightGeometry[] = {1, /* number of contours */
  4480.                                                   4, /* number of points */
  4481.                                                 0xff000000,
  4482.                                                             ff(50), ff(50), 
  4483.                                                             ff(200),  ff(200), 
  4484.                                                            ff(50), ff(200),
  4485.                                                             ff(200),  ff(50)};    
  4486.  
  4487.     aPathShape = GXNewPaths((gxPaths *) figureEightGeometry);
  4488.     GXSetShapeFill(aPathShape, gxClosedFrameFill);
  4489.  
  4490.     GXDrawShape(aPathShape);
  4491. }
  4492. Figure 3-48 shows the result of this sample function with the default pen width, which is a hairline, and the default pen placement, which is centered (as it always is for hairlines).
  4493. Figure 3-48    A hairline figure eight
  4494.  
  4495. To increase the width of the pen, you can add the following line of code to the CreateFigureEight sample function:
  4496. GXSetShapePen(aPathShape, ff(30));
  4497. which results in the shape depicted in Figure 3-49.
  4498. Figure 3-49    A thick figure eight
  4499.  
  4500. To change the placement of the thick pen, you can use the GXSetShapeStyleAttributes function to set the gxInsideFrameStyle or gxOutsideFrameStyle attributes. For example, if you add this line of code to the CreateFigureEight sample function: 
  4501. GXSetShapeStyleAttributes(aPathShape, gxInsideFrameStyle);
  4502. QuickDraw GX shifts the entire pen width, which is 30 points, to the inside of the figure eight. Since, by default, QuickDraw GX defines the inside of a contour to be the right side, contour direction is significant in this case, and the resulting shape appears as depicted in Figure 3-50.
  4503. Figure 3-50    A figure eight with the pen inset
  4504.  
  4505. If you indicate that the pen should be placed outside—that is, to the left of—the contour, using this line of code:
  4506. GXSetShapeStyleAttributes(aPathShape, gxOutsideFrameStyle);
  4507. the figure reverses, appearing as shown in Figure 3-51.
  4508. Figure 3-51    A figure eight with path outset
  4509.  
  4510. The contour direction of the path shape determines which side is the inside and which side is the outside. If you reverse the contour direction by reversing the order of the geometric points with this definition: 
  4511. long     figureEightGeometry[] = {1, /* number of contours */
  4512.                                             4, /* number of points */
  4513.                                       0xff000000, /* all off path */
  4514.                                         ff(200), ff(50)
  4515.                                        ff(50),  ff(200),
  4516.                                        ff(200), ff(200),
  4517.                                        ff(50),  ff(50)};    
  4518. but still set the gxOutsideFrameStyle attribute:
  4519. GXSetShapeStyleAttributes(aPathShape, gxOutsideFrameStyle);
  4520. then the resulting shape appears to be the same as the original figure-eight shape did with the path inset, as shown in Figure 3-52.                                
  4521. Figure 3-52    A reversed figure eight with path outset
  4522.  
  4523. However, this figure still doesn’t look like a figure eight with the path outset—it looks like a figure eight with the upper half of the path outset and the lower half of the path inset. This problem arises because the path crosses itself. To fix this problem, you can call the GXSimplifyShape function, which redefines the geometry of the shape so that the path has no crossed contours. Listing 3-8 shows a sample function that uses the GXSimplifyShape to remove the unwanted contour crossing.
  4524. Listing 3-8    Removing unwanted contour crossings
  4525.  
  4526. gxShape CreateUncrossedFigureEight()
  4527. {
  4528.     gxShape     aPathShape;
  4529.  
  4530.     long     figureEightGeometry[] = {1, /* number of contours */
  4531.                                                4, /* number of points */
  4532.                                          0xff000000,
  4533.                                            ff(50),  ff(50), 
  4534.                                            ff(200), ff(200), 
  4535.                                            ff(50),  ff(200),
  4536.                                            ff(200), ff(50)};    
  4537.                                    
  4538.     aPathShape = GXNewPaths((gxPaths *) figureEightGeometry);
  4539.     GXSetShapeFill(aPathShape, gxClosedFrameFill);
  4540.     GXSetShapePen(aPathShape, ff(30));
  4541.     GXSimplifyShape(aPathShape);
  4542.     GXSetShapeStyleAttributes(aPathShape, gxAutoInsetStyle);
  4543.     GXSetShapeStyleAttributes(aPathShape, gxOutsideFrameStyle);
  4544.     
  4545.     GXDrawShape(aPathShape);
  4546. }
  4547. This sample function calls GXSimplifyShape to uncross the contours of the figure eight. However, you cannot be sure whether GXSimplifyShape uncrosses the contours by reversing the direction of the upper half of the figure eight, making each loop clockwise, or by reversing the lower half of the figure eight, making each loop counterclockwise. Therefore, the CreateUncrossedFigureEight sample function sets the gxAutoInsetStyle style attribute, which overrides the default assumption that the right side of the contour is the inside. Instead, QuickDraw GX determines the true inside of each contour. 
  4548. Finally, now that the contours of the path do not cross and QuickDraw GX is determinng the actual inside of the contour, setting the gxOutsideFrameStyle attribute works more as you would expect, as shown in Figure 3-53.
  4549. Figure 3-53    Uncrossed figure eight with pen outset
  4550.  
  4551. Adding Caps to a Shape
  4552.  
  4553. To add a cap shape to the ends of another shape’s contours, you must create a cap record structure. The cap record structure has three fields: one for the start cap shape, one for the end cap shape, and one for the cap attributes.
  4554. Listing 3-9 shows how to create a cap record structure with an arrow head for the start cap, an arrow tail for the end cap, and no cap attributes.
  4555. Listing 3-9    Creating an arrow
  4556.  
  4557. gxShape CreateArrow()
  4558. {
  4559.     gxShape         aCurve, arrowHead, arrowTail;
  4560.  
  4561.     static gxCurve     curveGeometry = {ff(25),  ff(125), 
  4562.                                               ff(100), 0, 
  4563.                                               ff(225), ff(125)};    
  4564.     
  4565.     long        arrowHeadPolygonGeometry[] = {4, /* number of points */
  4566.                                                       -ff(3), 0,
  4567.                                                        0, fix1, 
  4568.                                                         fix1, 0, 
  4569.                                                 0, -fix1};
  4570.                                                
  4571.     long         arrowTailPolygonGeometry[] = {5, /* number of points */
  4572.                                                     -fix1, 0, 
  4573.                                                 0, fix1, 
  4574.                                                 ff(2), fix1, 
  4575.                                                 ff(2), -fix1, 
  4576.                                                 0, -fix1};
  4577.      gxCapRecord     theCapRecord;
  4578.  
  4579.  
  4580.     aCurve = GXNewCurve (&curveGeometry);
  4581.     
  4582.     arrowHead = NewPolygon((gxPolygon *) 
  4583.                                     &arrowHeadPolygonGeometry);
  4584.     arrowTail = NewPolygon((gxPolygon *) 
  4585.                                     &arrowTailPolygonGeometry);
  4586.  
  4587.     theCapRecord.startCap = arrowHead;
  4588.     theCapRecord.endCap = arrowTail;
  4589.     theCapRecord.attributes = gxNoAttributes;
  4590.  
  4591.     GXSetShapeCap(aCurve, &theCapRecord);
  4592.     
  4593.     GXDisposeShape(arrowHead);
  4594.     GXDisposeShape(arrowTail);
  4595.     
  4596.     GXSetShapePen(aCurve, ff(10));
  4597.     
  4598.     GXDrawShape(aCurve);
  4599. }
  4600. This sample function creates two polygon shapes: one for the arrow head and one for the arrow tail. It then creates a cap record structure that contains references to the two shape objects and an attributes field with no attributes set.
  4601. The sample function then calls the GXSetShapeCap function, which sets the cap property of the curve shape’s style object. (Remember, it makes a copy of this style object if the style is shared amongst multiple shapes.)
  4602. When the GXSetShapeCap function copies the start cap and the end cap from the cap record to the curve’s style object, it does not simply copy references to the arrow head polygon and the arrow tail polygon. Instead, it makes copies of those shapes and includes the copies in the cap property of the curve’s style. After setting the curve shape’s caps, you may subsequently make changes to the arrowHead and arrowTail shapes without affecting the start cap or end cap of the curve.
  4603. Note
  4604. Actually, the GXSetShapeCap function does not copy the entire start cap shape or end cap shape. Instead, it copies only the geometric information of the start and end cap shapes. For this reason, you must provide start cap shapes and end cap shapes in their primitive forms.u
  4605. After the CreateArrow sample function sets the caps of the curve shape, it disposes of the arrowHead and arrowTail polygons. At this point, the owner count of these shapes becomes 0 (since the curve’s style does not actually reference these shapes), and the memory used by the two polygon shapes is freed.
  4606. Note
  4607. Like the GXSetShapeCap function copies geometry information from the start and end cap shapes into a style’s cap property, the GXGetShapeCap function creates new shape objects and copies the geometry information from a style’s ca p property into the new shapes. If you use the GXGetShapeCap function to find the caps of a shape and alter those caps, you must use the GXSetShapeCap function to copy your changes back into the shape’s caps.u
  4608. Figure 3-54 shows the result of the CreateArrow sample function.
  4609. Figure 3-54    An arrow
  4610.  
  4611. Notice that QuickDraw GX rotates the start cap and the end cap to match the slope of the curve’s contour, and scales them by the width of the pen. You can suppress the rotation by setting the gxLevelStartCap and gxLevelEndCap cap attributes.
  4612. The sections “Cap Record Structure” on page 3-94 and “Cap Attributes” on page 3-95 describe the cap record structure and the cap attributes in more detail, and the section “Getting and Setting Start Caps and End Caps” on page 3-116 describes the functions you can use to manipulate caps.
  4613. Adding Standard Caps to a Shape
  4614.  
  4615. Two types of caps that you may frequently want to add to your shapes are the round cap and the square cap. The sample function in Listing 3-10 shows how to create these types of caps.
  4616. For a round cap, you need to create a semicircle, which you can do using the library routine NewArc. The fit the end of a contour, the bounds of this semicircle must be set as follows:
  4617. gxRectangle roundCapBounds = {-fl(.5), -fl(.5), fl(.5), fl(.5)};
  4618. and the semicircle must start at 180 degrees and span a 180 degree arc:
  4619. gxRoundCap = NewArc(&roundCapBounds, ff(180), ff(180), true);
  4620. For a square cap to fit the end of a contour, its bounds must be set as follows:
  4621. gxRectangle         squareCapBounds = {-ff(.5), -ff(.5), ff(0), ff(.5)};
  4622. Listing 3-10 shows how to create a round cap and a square cap for the curve shape from previous examples.
  4623. Listing 3-10    Adding round caps and square caps
  4624.  
  4625. gxShape CreateMyShape()
  4626. {
  4627.     gxShape             aCurve, gxRoundCap, gxSquareCap;
  4628.  
  4629.     static gxCurve     curveGeometry = {ff(25),  ff(125), 
  4630.                                               ff(100), 0, 
  4631.                                               ff(225), ff(125)};    
  4632.     
  4633.     gxRectangle             roundCapBounds = {-fl(.5), -fl(.5), 
  4634.                                             fl(.5), fl(.5)};
  4635.  
  4636.     gxRectangle         squareCapBounds = {-ff(.5), -ff(.5), 
  4637.                                              ff(0), ff(.5)};
  4638.     
  4639.      gxCapRecord     theCapRecord;
  4640.  
  4641.  
  4642.     aCurve = GXNewCurve (&curveGeometry);
  4643.         
  4644.     gxRoundCap = NewArc(&roundCapBounds, ff(180), ff(180), true);
  4645.     gxSquareCap = GXNewRectangle(&squareCapBounds);
  4646.  
  4647.     theCapRecord.startCap = gxRoundCap;
  4648.     theCapRecord.endCap = gxSquareCap;
  4649.     theCapRecord.attributes = gxNoAttributes;
  4650.  
  4651.     GXSetShapeCap(aCurve, &theCapRecord);
  4652.     
  4653.     GXDisposeShape(gxRoundCap);
  4654.     GXDisposeShape(gxSquareCap);
  4655.     
  4656.     GXSetShapePen(aCurve, ff(10));
  4657.     
  4658.     GXDrawShape(aCurve);
  4659. }
  4660. Figure 3-55 shows the result of this sample function.
  4661. Figure 3-55    Round and square caps
  4662.  
  4663. Notice that QuickDraw GX rotates and resizes the caps to fit the contour.
  4664. Adding Joins to a Shape
  4665.  
  4666. To add a join shape to the corners of another shape’s contours, you must create a join record structure. The join record structure has three fields: one for the join shape, one for the join attributes, and one for the miter, which is used only for sharp joins.
  4667. Listing 3-11 shows how to create a join record structure with an diamond shape as the join shape, and then apply the diamond join shape to the corners of a rectangle shape.
  4668. Listing 3-11    Adding joins to a shape
  4669.  
  4670. gxShape CreateJoinedSquare()
  4671. {
  4672.     gxShape             aSquareShape, aDiamondShape;
  4673.  
  4674.     gxRectangle         squareGeometry = {ff(50), ff(50), 
  4675.                                           ff(150), ff(150)};    
  4676.         
  4677.     long             diamondGeometry[] = {1, /* number of contours */
  4678.                                           4, /* number of points */
  4679.                                           ff(0), ff(3), 
  4680.                                           ff(1), fl(0),
  4681.                                           ff(0), -ff(3), 
  4682.                                           -ff(1), ff(0)};    
  4683.         
  4684.      gxJoinRecord         theJoinRecord;
  4685.     
  4686.     
  4687.     aSquareShape = GXNewRectangle(&squareGeometry);
  4688.     GXSetShapeFill(aSquareShape, gxClosedFrameFill);
  4689.  
  4690.     aDiamondShape = GXNewPolygons((gxPolygons *) diamondGeometry);
  4691.         
  4692.     theJoinRecord.attributes = gxNoAttributes;
  4693.     theJoinRecord.join = aDiamondShape;
  4694.     theJoinRecord.miter = 0; 
  4695.  
  4696.     GXSetShapeJoin(aSquareShape, &theJoinRecord);
  4697.     
  4698.     GXDisposeShape(aDiamondShape);
  4699.         
  4700.     GXSetShapePen(aSquareShape, ff(10));
  4701.     
  4702.     GXDrawShape(aSquareShape);
  4703. }
  4704. This sample function creates a square as the shape to be joined and a diamond-shaped polygon to use for the joins. It then creates a join record structure which contains a reference to the diamond shape, an attributes field with no attributes set, and a miter of 0.
  4705. The sample function then calls the GXSetShapeJoin function, which sets the join property of the square shape’s style object. (Remember, it makes a copy of this style object if the style is shared amongst multiple shapes.)
  4706. Note
  4707. As with caps, QuickDraw GX copies only the geometric information of the join shape into the join property of the style object; it does not copy the entire join shape. For this reason, join shapes must be in their primitive form. Once you have called GXSetShapeJoin, you are free to change the original join shape without affecting the joins of the joined shape.u
  4708. After the CreateJoinedSquare sample function sets the joins of the square shape, it disposes of the aDiamondShape polygon. At this point, the owner count of this polygon shape becomes zero and the memory used by the polygon shape is freed.
  4709. Figure 3-54 shows the result of the CreateJoinedSquare sample function.
  4710. Figure 3-56    A square with diamond-shaped joins
  4711.  
  4712. Notice that QuickDraw GX scales the join shape by the pen width and rotates the join shape to match the mid-angle of the two line segments that make each corner. You can suppress the rotation by setting the gxLevelJoin join attribute:
  4713. theJoinRecord.attributes = gxLevelJoin;
  4714. Figure 3-57 shows the result of setting this attribute.
  4715. Figure 3-57    Level joins
  4716.  
  4717. The sections “Join Record Structure” on page 3-95 and “Join Attributes” on page 3-96 describe the join record and join attributes in more detail, and the section “Getting and Setting Joins” on page 3-121 describes the functions you canuse to manipulate joins.
  4718. The next section shows how to create standard joins and how to use the miter field of the join record structure.
  4719. Adding Standard Joins to a Shape
  4720.  
  4721. Two types of joins that you may frequently want to add to your shapes are the round join and the square join. Unlike the standard cap shapes, which you add yourself by creating a semicircle shape or a half-square shape, the standard join shapes are provided for you by QuickDraw GX.
  4722. To create a standard join shape, you set the join field of the join record to nil, which indicates that you are not providing a join shape, and you set the gxSharpJoin join attribute or the gxCurveJoin join attribute, which indicates that you want QuickDraw GX to generate one of the standard joins for you.
  4723. Listing 3-10 shows how to add a sharp join to an angle shape.
  4724. Listing 3-12    Adding a sharp join to an angle shape
  4725.  
  4726. gxShape CreateSharpJoin()
  4727. {
  4728.     gxShape             anAngleShape;
  4729.  
  4730.     long             angleGeometry[] = {1, /* number of contours */
  4731.                                         3, /* number of points */
  4732.                                         ff(20), ff(20), 
  4733.                                         ff(250), ff(60), 
  4734.                                         ff(20), ff(100)};    
  4735.         
  4736.      gxJoinRecord         theJoinRecord;
  4737.  
  4738.     anAngleShape = GXNewPolygons((gxPolygons *) angleGeometry);
  4739.     GXSetShapeFill(anAngleShape, gxOpenFrameFill);
  4740.         
  4741.     theJoinRecord.attributes = gxSharpJoin;
  4742.     theJoinRecord.join = nil;
  4743.     theJoinRecord.miter = gxPositiveInfinity; 
  4744.  
  4745.     GXSetShapeJoin(anAngleShape, &theJoinRecord);
  4746.         
  4747.     GXSetShapePen(anAngleShape, ff(15));
  4748.     
  4749.     GXDrawShape(anAngleShape);
  4750. }
  4751. Notice that this sample function sets the miter field to the constant value gxPositiveInfinity, which indicates the join should be as sharp as necessary.
  4752. Figure 3-58 shows the result of this sample function.
  4753. Figure 3-58    Very sharp join
  4754.  
  4755. If you limit the miter of the sharp join, for example, with the code
  4756. theJoinRecord.miter = ff(1); /* scaled by pen width */
  4757. QuickDraw GX limits the distance between the actual corner of the contour as specified in the shape’s geometry and the tip of the corner as actually drawn. Since miter is scaled by pen width, and the pen width in this example is 15, QuickDraw GX truncates the sharp join 15 points away from the actual corner of the geometry, as shown in Figure 3-59.
  4758. Figure 3-59    A truncated sharp join
  4759.  
  4760. The sections “Join Record Structure” on page 3-95 and “Join Attributes” on page 3-96 describe the join record structure and the join attributes in more detail, and the section “Getting and Setting Joins” on page 3-121 describes the functions you can use to manipulate joins.
  4761. Dashing a Shape
  4762.  
  4763. To add a dash shape along the contours of another shape, you must create a dash record structure. The dash record structure has five fields:
  4764. n    the dash attributes, which modify the way the shape is dashed
  4765. n    the dash shape, which contains the shape to use as the dashes
  4766. n    the dash advance, which determines the number of points between the start of one dash and the start of the next
  4767. n    the dash phase, which determines how far into the advance the dashing should start
  4768. n    the dash scale, which you can use to counteract the automatic scaling of the dash shape
  4769. The sample function in Listing 3-13 creates a curve shape dashed with diamonds. First, it creates the curve shape and the diamond shape. The diamond shape has a height and a width of 30 points.
  4770. The sample function then creates a dash record structure for the diamond dashes, and calls the GXSetShapeDash function to set the dash property of the curve shape’s style.
  4771. Listing 3-13    Creating a curve shape dashed with diamonds
  4772.  
  4773. gxShape CreateDashedCurve()
  4774. {
  4775.     gxShape             aCurveShape, aDiamondShape;
  4776.  
  4777.     static gxCurve     curveGeometry = {ff(50), ff(125), 
  4778.                                                ff(125), 0, 
  4779.                                                ff(250), ff(125)};    
  4780.         
  4781.     long             diamondGeometry[] = {1, /* number of contours */
  4782.                                           4, /* number of points */
  4783.                                           ff(0), ff(15), 
  4784.                                           ff(15), fl(0),
  4785.                                           ff(0), -ff(15), 
  4786.                                           -ff(15), ff(0)};     
  4787.  
  4788.         
  4789.      gxDashRecord         theDashRecord;
  4790.     
  4791.     
  4792.     aCurveShape = GXNewCurve (&curveGeometry);
  4793.  
  4794.     aDiamondShape = GXNewPolygons((gxPolygons *) diamondGeometry);
  4795.         
  4796.     theDashRecord.attributes = gxNoAttributes;  
  4797.     theDashRecord.dash = aDiamondShape;
  4798.     theDashRecord.advance = ff(40); 
  4799.     theDashRecord.phase = 0; 
  4800.     theDashRecord.scale = ff(30); 
  4801.  
  4802.     GXSetShapeDash(aCurveShape, &theDashRecord);
  4803.     
  4804.     GXDisposeShape(aDiamondShape);
  4805.         
  4806.     GXSetShapePen(aCurveShape, ff(30));
  4807.     
  4808.     GXDrawShape(aCurveShape);
  4809. }
  4810. Note
  4811. As with caps and joins, QuickDraw GX copies only the geometric information of the dash shape into the dash property of the style object; it does not copy the entire dash shape. For this reason, the dash shape must be in its primitive form. Once you have called GXSetShapeDash, you are free to change the original dash shape without affecting the dashes of the dashed shape.u
  4812. Notice that this sample function sets the dash advance to 40. Since the diamond shape is 30 points wide, this dash advance allows for 10 points between dashes. The dash phase is set to 0, which indicates that the origin of the first dash should be aligned with the beginning of the curve contour exactly. 
  4813. Since QuickDraw GX scales dashes (perpendicularly to the dashed contour) by the pen width, the dashes in this example would be 900 points from tip to tip, as the diamond shape itself is 30 points high and the pen width of the curve is also 30 points. However, the sample function sets the dash scale to 30, by which QuickDraw GX scales the dashes down (again, perpendicularly to the dashed contour), which leaves the diamond shapes with their original size.
  4814. Figure 3-60 shows the result of the CreateDashedCurve sample function.
  4815. Figure 3-60    Dashed curve
  4816.  
  4817. If you provide a smaller value for the dash scale, QuickDraw GX scales the dashes up in the direction perpendicular to the dashed contour. For example, if you provide a dash scale half as large:
  4818. theDashRecord.scale = ff(15);
  4819. the dashes become twice the size in the direction perpendicular to the curve, as shown in Figure 3-61.
  4820. Figure 3-61     Scaled dashes
  4821.  
  4822. The dashes are now actually wider than the pen width of the curve. You can set the gxClipDash dash attribute to draw only the parts of the dashes that lie within the curve’s pen width. For example, adding this line of code to the sample function:
  4823. theDashRecord.attributes = gxClipDash;  
  4824. creates the shape shown in Figure 3-62.
  4825. Figure 3-62    Clipped dashes
  4826.  
  4827. Notice that QuickDraw GX not only clips the dashes to the width of the curve, but also clips them at the ends of the curve. To shift the dashes along the curve so that the first dash shows whole, you can adjust the dash phase. For example, this line of code:
  4828. theDashRecord.phase = GXFloatToFract(0.50); 
  4829. shifts the dashes forward one half of the dash advance. Since the dash advance in this case is 40, the dashes are shifted forward 20 points, as shown in Figure 3-63.
  4830. Figure 3-63    Phased dashes
  4831.  
  4832. In this case, adjusting the dash phase is sufficient to cause a whole number of dashes to show. In other cases, you may have to use the gxAutoAdvanceDash attribute, which is described in the next section.
  4833. The sections “Dash Record Structure” on page 3-97 and “Dash Attributes” on page 3-98 describe the dash record and dash attributes in more detail, and the section “Getting and Setting Dashes” on page 3-126 describes the functions you can use to manipulate dashes.
  4834. Adjusting Dashes to Fit Contours
  4835.  
  4836. Sometimes the dash advance does not divide evenly into the length of a contour and the dashes don’t look quite right. QuickDraw GX provides the gxAutoAdvanceDash dash attribute to handle this situation.
  4837. For example, the sample function in Listing 3-14 creates a circle dashed with kite-shaped diamonds. It does not use the gxAutoAdvanceDash dash attribute.
  4838. Listing 3-14    Creating a dashes circle
  4839.  
  4840. gxShape CreateDashedCircle()
  4841. {
  4842.     gxShape             aCircleShape, aDiamondShape;
  4843.  
  4844.     gxRectangle        circleBounds = {ff(50), ff(50), ff(180), ff(180)};
  4845.     
  4846.     long             diamondGeometry[] = {1, /* number of contours */
  4847.                                           4, /* number of points */
  4848.                                           ff(0), ff(20), 
  4849.                                           ff(15), fl(0),
  4850.                                           ff(0), -ff(40), 
  4851.                                           -ff(15), ff(0)};
  4852.         
  4853.      gxDashRecord         theDashRecord;
  4854.     
  4855.     
  4856.     aCircleShape = NewArc(&circleBounds, ff(0), ff(360), false);
  4857.     GXSetShapeFill(aCircleShape, gxHollowFill);
  4858.  
  4859.     aDiamondShape = GXNewPolygons((gxPolygons *) diamondGeometry);
  4860.         
  4861.     theDashRecord.attributes = gxNoAttributes;  
  4862.     theDashRecord.dash = aDiamondShape;
  4863.     theDashRecord.advance = ff(30); 
  4864.     theDashRecord.phase = 0; 
  4865.     theDashRecord.scale = ff(60); 
  4866.  
  4867.     GXSetShapeDash(aCircleShape, &theDashRecord);
  4868.     
  4869.     GXDisposeShape(aDiamondShape);
  4870.         
  4871.     GXSetShapePen(aCircleShape, ff(60));
  4872.     
  4873.     GXDrawShape(aCircleShape);
  4874. }
  4875. Since this sample function does not set the gxAutoAdvanceDash dash attribute, and the dash advance of 30 does not divide evenly into the circumference of the circle, this function results in the shape shown in Figure 3-64.
  4876. Figure 3-64    Circle dashed with diamonds
  4877.  
  4878. Notice that the initial dash and the final dash overlap. (The overlapping region is not filled, because, by default, the dash shape has winding shape fill.)
  4879. If, however, you set the gxAutoAdvanceDash dash attribute, using this line of code:
  4880. theDashRecord.attributes = gxAutoAdvanceDash;  
  4881. QuickDraw GX adjusts the dash advance accordingly. The result is shown in Figure 3-65.
  4882. Figure 3-65    Automatically advanced dashes
  4883.  
  4884. As you can see, QuickDraw GX adjusts the dash advance the smallest amount possible to create a whole number of dashes along the contour.
  4885. The sections “Dash Record Structure” on page 3-97 and “Dash Attributes” on page 3-98 describe the dash record and dash attributes in more detail, and the section “Getting and Setting Dashes” on page 3-126 describes the functions you can use to manipulate dashes.
  4886. Insetting Dashes
  4887.  
  4888. You can use a number of methods to change the placement of the dash shape relative to the dashed contour. For example, you can
  4889. n    set the inside-frame style attribute or outside-frame style attribute of the style object containing the dash information so that QuickDraw GX places the dashes on the inside or outside of the contours
  4890. n    change the geoemtry of the dash shape so that QuicDraw GX changes the placement the dash shape correspondingly when dashing the shape
  4891. These two methods produce substantially different results. For example, if you inset the pen placement in the example from the previous section by adding the call
  4892. GXSetShapeStyleAttributes(aCircleShape, gxInsideFrameStyle);
  4893. to the CreateADashedCircle sample function, QuickDraw GX automatically adjusts the number and spacing of the dashes to fit the inset circle, as shown in Figure 3-66.
  4894. Figure 3-66    Circle with diamond dashes inset
  4895.  
  4896. In this case, the number of dashes has been drastically reduced. If you want to keep the number of dashes constant, but move them towards the center of the circle, change the geometry of the dash shape instead of insetting the pen. For example, you can alter the diamond geometry from the CreateADashedCircle sample function by translating it up 30 points in the y-coordinate direction using this defintion:
  4897. long             diamondGeometry[] = {1, /* number of contours */
  4898.                                        4, /* number of points */
  4899.                                        ff(0), ff(50), 
  4900.                                        ff(15), ff(30),
  4901.                                        ff(0), -ff(10), 
  4902.                                        -ff(15), ff(30)};
  4903. In this case, if you do not inset the pen of the circle shape, the resulting shape maintains the greater number of dashes, but fits within the smaller circle, as shown in Figure 3-67.
  4904. Figure 3-67    Circle with diamond dashes moved toward the center
  4905.  
  4906. Breaking and Bending Dashes
  4907.  
  4908. You can use polygon shapes and path shapes as dash shapes, which means you can have a dash shape that has multiple contours. The way that QuickDraw GX place dashes along a contour can cause dashes with multiple contours to appear quite a distance from the dashed contour. QuickDraw GX provides the gxBreakDash and gxBendDash dash attributes to address this problem.
  4909. As an example, you can create a dash shape with two entirely separate contours: for example, two separate diamonds, as shown in Figure 3-68.
  4910. Figure 3-68    Dash shape with two contours
  4911.  
  4912. When you use this shape to dash any sort of curve, the larger diamond falls entirely off of the contour. Listing 3-15 creates a circle shape and dashes with the double diamond shape.
  4913. Listing 3-15    Creating a dash with multiple contours
  4914.  
  4915. gxShape CreateDoubleDiamondDash()
  4916. {
  4917.     gxShape              aCircleShape, aDiamondShape;
  4918.  
  4919.     gxRectangle         circleBounds = {ff(50), ff(50), ff(180), ff(180)};
  4920.     
  4921.     long              doubleDiamond[] = {2, /* number of contours */
  4922.                                          4, /* number of points */
  4923.                                          ff(0), ff(10), 
  4924.                                          ff(10), ff(0),
  4925.                                          ff(0), -ff(10), 
  4926.                                          -ff(10), ff(0),
  4927.                                          4, /* number of points */
  4928.                                          ff(40), ff(10), 
  4929.                                          ff(60), ff(0),
  4930.                                          ff(40), -ff(10), 
  4931.                                          ff(20), ff(0)};
  4932.         
  4933.      gxDashRecord         theDashRecord;
  4934.     
  4935.     
  4936.     aCircleShape = NewArc(&circleBounds, ff(0), ff(360), false);
  4937.     GXSetShapeFill(aCircleShape, gxHollowFill);
  4938.  
  4939.     aDiamondShape = GXNewPolygons((gxPolygons *) doubleDiamond);
  4940.         
  4941.     theDashRecord.attributes = gxAutoAdvanceDash;  
  4942.     theDashRecord.dash = aDiamondShape;
  4943.     theDashRecord.advance = ff(80); 
  4944.     theDashRecord.phase = GXFloatToFract(0.0); 
  4945.     theDashRecord.scale = ff(60); 
  4946.  
  4947.     GXSetShapeDash(aCircleShape, &theDashRecord);
  4948.     
  4949.     GXDisposeShape(aDiamondShape);
  4950.         
  4951.     GXSetShapePen(aCircleShape, ff(60));
  4952.     
  4953.     return(aCircleShape);
  4954. }
  4955. This sample function creates the shape depicted in Figure 3-69.
  4956. Figure 3-69    Circle dashed with double diamonds
  4957.  
  4958. The gxBreakDash dash attribute indicates that each contour of the dash shape should be separately rotated and placed on the dashed contour. If you set the gxBreakDash dash attribute in this example by replacing this line of code in the sample function:
  4959. theDashRecord.attributes = gxAutoAdvanceDash;  
  4960. with this line of code:
  4961. theDashRecord.attributes = gxAutoAdvanceDash | gxBreakDash;  
  4962. the resulting shape appears as shown in Figure 3-70.
  4963. Figure 3-70    Circle with dashes broken
  4964.  
  4965. In this case, QuickDraw GX rotates and centers the large diamond contours (separately from the small diamond contours) to fit the dashed contour.
  4966. If you change the pen width of the circle in this example to 0, you get a hairline curve, and the dashes are mapped down to their one-dimensional image. So, for example, setting the pen width with the call
  4967. GXSetShapePen(aCircleShape, ff(0));
  4968. causes the dashes circle to appear as in Figure 3-71.
  4969. Figure 3-71    Circle with airline dashes
  4970.  
  4971. QuickDraw GX provides an extra feature for hairline dashes: you can bend them to fit curved contours exactly.
  4972. For example, if you change the dash attributes in this example using the assignment
  4973. theDashRecord.attributes = gxAutoAdvanceDash | gxBreakDash | 
  4974.                                     gxBendDash;  
  4975. the dashed circle appears as shown in Figure 3-72.
  4976. Figure 3-72    Circle with bent hairline dashes
  4977.  
  4978. Note that you can specity the gxBendDash dash attribute only for hairline contours.
  4979. The sections “Dash Record Structure” on page 3-97 and “Dash Attributes” on page 3-98 describe the dash record structure and dash attributes in more detail, and the section “Getting and Setting Dashes” on page 3-126 describes the functions you can use to manipulate dashes.
  4980. Wrapping Text
  4981.  
  4982. You can wrap text to a contour by using a typographic shape as the dash shape. Since dashes must always be primitive shapes, you must convert a text or layout shape to a glyph or path shape before using it as a dash shape.
  4983. The sample function in Listing 3-16 creates a text shape, sets its font and font size, converts it to a path shape, and uses it to dash a curve.
  4984. Listing 3-16    Wrapping text
  4985.  
  4986. gxShape WrapText()
  4987. {
  4988.     gxShape             aCurveShape, aTextShape;
  4989.  
  4990.     static gxCurve     curveGeometry = {ff(25), ff(125), 
  4991.                                             ff(100), 0, 
  4992.                                             ff(225), ff(125)};    
  4993.  
  4994.      gxDashRecord         theDashRecord;
  4995.  
  4996.  
  4997.     aCurveShape = GXNewCurve(&curveGeometry);
  4998.     GXSetShapeFill(aCurveShape, gxOpenFrameFill);
  4999.     
  5000.     aTextShape = GXNewText(13,
  5001.                                   (unsigned char *) "QuickDraw™ GX",  
  5002.                                   nil);
  5003.     SetShapeCommonFont(aTextShape, timesFont);
  5004.     GXSetShapeTextSize(aTextShape, ff(35));
  5005.     GXSetShapeType(aTextShape, gxPathType);
  5006.  
  5007.     theDashRecord.attributes = gxBreakDash;  
  5008.     theDashRecord.dash = aTextShape;
  5009.     theDashRecord.advance = ff(330); 
  5010.     theDashRecord.phase = 0; 
  5011.     theDashRecord.scale = ff(35); 
  5012.  
  5013.     GXSetShapeDash(aCurveShape, &theDashRecord);
  5014.     GXDisposeShape(aTextShape);
  5015.         
  5016.     GXSetShapePen(aCurveShape, ff(35));
  5017.     
  5018.     return(aCurveShape);
  5019. }
  5020. This example sets the dash scale to equal the text size so that the glyphs do not become distorted by dash scaling.
  5021. The result of this function is depicted in Figure 3-73. Notice that QuickDraw GX rotates and places each glyph separately on the contour.
  5022. Figure 3-73    Wrapped text
  5023.  
  5024. Inside Macintosh: QuickDraw GX Typography contains more information about using the typographic shapes.
  5025. Determining Dash Positions
  5026.  
  5027. A restriction of the QuickDraw GX dashing architecture is that each dash must be the same shape. There may be a situation where you’d like to dash a contour and have the dashes change as they progress along the contour.
  5028. To help you create the appearance of a dashed contours where the dashes change, QuickDraw GX provides the GXGetShapeDashPositions function. This function returns a list of mappings that identify the position and rotation of each dash on a shape.
  5029. By placing shapes in a picture using this list of mappings, you can give the effect of a contour with changing dashes.
  5030. As an example, the sample functions in this section show you how to create a picture of a clock. The CreateDashedCircle sample function in Listing 3-17 creates a circle with 12 dashes, each of which appears where a number would appear on a clock.
  5031. Listing 3-17    Creating a circle with 12 dashes
  5032.  
  5033. gxShape CreateDashedCircle()
  5034. {
  5035.     gxShape             aCircleShape, aSquareShape;
  5036.  
  5037.     gxRectangle         circleBounds = {ff(50), ff(50), 
  5038.                                         ff(180), ff(180)};
  5039.     
  5040.     gxRectangle         squareBounds = {-ff(10), -ff(10), 
  5041.                                         ff(10),  ff(10)};
  5042.     
  5043.      gxDashRecord         theDashRecord;
  5044.     
  5045.     aCircleShape = NewArc(&circleBounds, ff(30), ff(350), false);
  5046.     GXSetShapeFill(aCircleShape, gxClosedFrameFill);
  5047.     GXSetShapePen(aCircleShape, ff(60));
  5048.  
  5049.     aSquareShape = GXNewRectangle(&squareBounds);
  5050.     GXSetShapeFill(aSquareShape, gxEvenOddFill);
  5051.         
  5052.     theDashRecord.attributes = gxAutoAdvanceDash | gxLevelDash;  
  5053.     theDashRecord.dash = aSquareShape;
  5054.     theDashRecord.advance = ff(34); 
  5055.     theDashRecord.phase = 0; 
  5056.     theDashRecord.scale = ff(60); 
  5057.  
  5058.     GXSetShapeDash(aCircleShape, &theDashRecord);
  5059.     GXDisposeShape(aSquareShape);
  5060.     
  5061.     GXDrawShape(aCircleShape);
  5062. }
  5063. This sample function creates a square shape using the GXNewRectangle function to use as a dash for a circle shape created using the library function NewArc.
  5064. Note
  5065. Actually, the sample function does not create an entire circle due to an anomaly in the implementation of the NewArc library routine. When this routine detects a request for an arc of 360 degrees or more, it calls the NewOval library routine, which always starts a circular path at the far left postion. By specifying an arc of slightly less than 360 degrees, the NewArc library routine allows you to start the arc path at any angle. In this case, the sample application starts the arc at 30 degrees—the position of the 1 on a clock.u
  5066. The result of this function is shown in Figure 3-74.
  5067. Figure 3-74    Dash positions for a clock
  5068.  
  5069. To replace the square dashes with numbers, the sample function in Listing 3-18 calls the GetDashPositions function to obtain an array of mappings that identify the position and rotation of each dash. (Notice that the dashes are not rotated in this case since the gxLevelDash dash attribute is set.)
  5070. The sample function in Listing 3-18 then creates a picture and adds to it text shapes containing the numbers 1 through 12. Each time text is added to the picture, its mapping is set to be the next mapping in the array of dash positions.
  5071. Listing 3-18    Creating a clock shape
  5072.  
  5073. gxShape CreateAClock()
  5074. {
  5075.     gxShape             aCircleShape, aTextShape, aSquareShape, aPicture;
  5076.  
  5077.     gxRectangle         circleBounds = {ff(50), ff(50), ff(180), ff(180)};
  5078.     
  5079.     gxRectangle         squareBounds = {-ff(10), -ff(10), 
  5080.                                         ff(10),  ff(10)};
  5081.     
  5082.     gxPoint            textPosition = {ff(0), ff(0)};
  5083.     
  5084.     char*            numbers[] = {" 1", " 2", " 3", " 4", " 5", " 6", 
  5085.                                  " 7", " 8", " 9", "10", "11", "12"};
  5086.         
  5087.      gxDashRecord         theDashRecord;
  5088.     
  5089.     long     numberOfDashes, count;
  5090.     gxMapping             dashMappings[12];
  5091.  
  5092.      /* Create the dashed circle from the previous example. */
  5093.  
  5094.     aCircleShape = NewArc(&circleBounds, ff(30), ff(350), false);
  5095.     GXSetShapeFill(aCircleShape, gxClosedFrameFill);
  5096.  
  5097.     aSquareShape = GXNewRectangle(&squareBounds);
  5098.     GXSetShapeFill(aSquareShape, gxEvenOddFill);
  5099.         
  5100.     theDashRecord.attributes = gxAutoAdvanceDash | gxLevelDash;  
  5101.     theDashRecord.dash = aSquareShape;
  5102.     theDashRecord.advance = ff(34); 
  5103.     theDashRecord.phase = GXFloatToFract(0.0); 
  5104.     theDashRecord.scale = ff(60); 
  5105.  
  5106.     GXSetShapeDash(aCircleShape, &theDashRecord);
  5107.     GXSetShapePen(aCircleShape, ff(60));
  5108.  
  5109.     /* Find the dash positions. */
  5110.     numberOfDashes = GXGetShapeDashPositions(aCircleShape,
  5111.                                                          dashMappings);
  5112.     GXDisposeShape(aCircleShape);
  5113.     GXDisposeShape(aSquareShape);
  5114.     
  5115.     /* Create a picture with numbered text shapes. */
  5116.  
  5117.     aTextShape = GXNewText(1, (unsigned char*) "1", &textPosition);
  5118.     GXSetShapeFill(aTextShape, gxEvenOddFill);
  5119.         
  5120.     aPicture = GXNewShape(gxPictureType);    
  5121.     GXSetShapeAttributes(aPicture, gxUniqueItemsShape);
  5122.     for (count = 0; count <= numberOfDashes; count++) {
  5123.         GXSetShapeMapping(aTextShape, dashMappings[count]);
  5124.         GXSetText(aTextShape, 2, numbers[count], &textPosition);
  5125.         AddToShape(aPicture, aTextShape);
  5126.     }
  5127.     GXDisposeShape(aTextShape);
  5128.     
  5129.     GXDrawShape(aPicture);
  5130. }
  5131. The result of the CreateAClock sample function is depicted in Figure 3-75.
  5132. Figure 3-75    A clock shape
  5133.  
  5134. This sample function uses some concepts from other parts of QuickDraw GX. For more information
  5135. n    about mappings, see the chapter “Transform objects” of Inside Macintosh: QuickDraw GX Objects.
  5136. n    about pictures and adding elements to them, see Chapter 6, “Picture Shapes.” 
  5137. n    about typographic shapes, see Inside Macintosh: QuickDraw GX Typography.
  5138. Adding a Pattern to a Shape
  5139.  
  5140. To add a pattern to a shape, you must create a pattern record. The pattern record has four fields: the shape to use as the pattern, the patterm attributes, and a pair of vectors that define the grid over which QuickDraw GX places the pattern.
  5141. The sample function in Listing 3-19 creates a large rectangle shape patterned with small squares. 
  5142. Listing 3-19    Patterning a shape
  5143.  
  5144. gxShape CreatePatternedRectangle()
  5145. {
  5146.     gxShape             aRectangleShape, aSquarePattern;
  5147.  
  5148.     gxRectangle         rectangleGeometry = {ff(50), ff(50), 
  5149.                                              ff(250), ff(150)};    
  5150.  
  5151.     gxRectangle         squareGeometry = {ff(0), ff(0), 
  5152.                                           ff(10), ff(10)};    
  5153.                 
  5154.      gxPatternRecord     thePatternRecord;
  5155.     
  5156.     
  5157.     aRectangleShape = GXNewRectangle(&rectangleGeometry);
  5158.  
  5159.     aSquarePattern = GXNewRectangle(&squareGeometry);
  5160.         
  5161.     thePatternRecord.attributes = gxNoAttributes;
  5162.     thePatternRecord.pattern = aSquarePattern;
  5163.     thePatternRecord.u.x = ff(0);
  5164.     thePatternRecord.u.y = ff(20);
  5165.     thePatternRecord.v.x = ff(20);
  5166.     thePatternRecord.v.y = ff(0);
  5167.  
  5168.     GXSetShapePattern(aRectangleShape, &thePatternRecord);
  5169.     GXDisposeShape(aSquarePattern);
  5170.         
  5171.     GXDrawShape(aRectangleShape);
  5172. }
  5173. Note
  5174. Note
  5175. As with caps, joins, and dashes, QuickDraw GX copies only the geometric information of the pattern shape into the pattern property of the style object; it does not copy the entire pattern shape. For this reason, pattern shapes must be in primitive form. Once you have called GXSetShapePattern, you are free to change the original pattern shape without affecting the pattern of the patterned shape.u
  5176. Notice that this sample function creates a square pattern shape 10 points high by 10 points wide. It places that square pattern on a rectangular grid 20 points high by 20 points wide, resulting in the shape shown inFigure 3-76.
  5177. Figure 3-76    A patterned rectangle
  5178.  
  5179. Although this example places the pattern shape on a rectangular grid, you are not limited to rectangular grids. The u and v fields of the pattern record allow you to define a pair of vectors, so your pattern can be placed on any regular lattice.
  5180. QuickDraw GX does not limit you to patterning filled shapes; you can pattern framed shapes as well. For example, if you change the previous example so that the rectangle shape is framed using the call
  5181. GXSetShapeFill(aRectangleShape, gxClosedFrameFill);
  5182. and has a thick pen width using the call
  5183. GXSetShapePen(aRectangleShape, ff(40));
  5184. the resulting function creates the shape shown in Figure 3-77.
  5185. Figure 3-77    Patterning a framed shape
  5186.  
  5187. You can also pattern dashed shapes. For examples, see “Combining Caps, Joins, Dashes, and Patterns” on page 3-86.
  5188. The sections “Pattern Record Structure” on page 3-99 and “Pattern Attributes” on page 3-100 describe the pattern record structure and pattern attributes in more detail, and the section “Getting and Setting Patterns” on page 3-132 describes the functions you can use to manipulate patterns.
  5189. Determining Pattern Positions
  5190.  
  5191. As with the dashing model, the QuickDraw GX patterning model provides only for the case where the pattern shape remains the same throughout the entire patterned shape. If you want to pattern a shape and have the pattern change throughout it, you must use the GXGetShapePatternPositions function. This function returns an array of points that identify the location of each pattern shape on the patterned shape.
  5192. As an example, the sample function in this section shows you how to alter the patterned rectangle from the previous section. The sample function in Listing 3-20 first creates the patterned rectangle shown in Figure 3-76 and then uses the GXGetShapePatternPositions function to find the position of each small square in that patterned rectangle. The sample function then creates a picture, adding small squares at the appropriate positions, but rotating each new square a small amount.
  5193. Listing 3-20    Changing a pattern throughout a patterned shape
  5194.  
  5195. gxShape CreateBizarrePattern()
  5196. {
  5197.     gxShape aRectangleShape, smallRectangle, aPicture;
  5198.  
  5199.     gxRectangle         rectangleGeometry = {ff(50), ff(50), 
  5200.                                              ff(250), ff(150)};    
  5201.  
  5202.     gxRectangle         smallRectGeometry = {ff(0), ff(0), 
  5203.                                              ff(10), ff(10)};    
  5204.                 
  5205.     gxPatternRecord     thePatternRecord;
  5206.  
  5207.      gxPoint *patternPositions;
  5208.  
  5209.     int     numberOfPatterns, count;
  5210.     
  5211.     
  5212.     aRectangleShape = GXNewRectangle(&rectangleGeometry);
  5213.     GXSetShapeFill(aRectangleShape, gxEvenOddFill);
  5214.  
  5215.     smallRectangle = GXNewRectangle(&smallRectGeometry);
  5216.     GXSetShapeFill(smallRectangle, gxEvenOddFill);
  5217.         
  5218.     thePatternRecord.attributes = gxPortAlignPattern;
  5219.     thePatternRecord.pattern = smallRectangle;
  5220.     thePatternRecord.u.x = ff(0);
  5221.     thePatternRecord.u.y = ff(20);
  5222.     thePatternRecord.v.x = ff(20);
  5223.     thePatternRecord.v.y = ff(0);
  5224.  
  5225.     GXSetShapePattern(aRectangleShape, &thePatternRecord);
  5226.     
  5227.     numberOfPatterns = GXGetShapePatternPositions(aRectangleShape,
  5228.                                                                 nil);
  5229.     patternPositions = (gxPoint *) 
  5230.                               NewPtr(numberOfPatterns * sizeof(gxPoint));
  5231.     GXGetShapePatternPositions(aRectangleShape, patternPositions);
  5232.     
  5233.     GXDisposeShape(aRectangleShape);
  5234.             
  5235.     aPicture = GXNewShape(gxPictureType);    
  5236.     GXSetShapeAttributes(aPicture, gxUniqueItemsShape);
  5237.     for (count = 0; count < numberOfPatterns; count++) {
  5238.         GXRotateShape(smallRectangle, ff(10), 0, 0);
  5239.         GXMoveShapeTo(smallRectangle, patternPositions[count].x,
  5240.                          patternPositions[count].y);
  5241.         AddToShape(aPicture, smallRectangle);
  5242.     }
  5243.     GXDisposeShape(smallRectangle);
  5244.     DisposePtr((Ptr)patternPositions);
  5245.     
  5246.     return(aPicture);
  5247. }
  5248. This function calls the GXGetShapePatternPositions function twice. The first time, it sends nil as the value of the pattern positions array, which indicates that the GXGetShapePatternPositions function should not return an actual array of positions, but should return as the function result the total number of pattern positions. Once the sample function has this total, it allocates enough memory to hold the array of pattern postions, and then calls GXGetShapePatternPositions again to determine the actual positions.
  5249. The result of this sample function is shown in Figure 3-78.
  5250. Figure 3-78    Shape with changing pattern
  5251.  
  5252. Notice that, in this case, the list of positions returned by GXGetShapePatternPositions starts at the upper-left corner and works down each column of the patterned shape. In general, the order of the positions returned by the GXGetShapePatternPositions function is not guaranteed by QuickDraw GX.
  5253. This sample function uses some concepts from other parts of QuickDraw GX. For more information
  5254. n    about rotating and moving shapes, see the chapter “Transform Objects” in Inside Macintosh: QuickDraw GX Objects.
  5255. n    about pictures and adding elements to them, see Chapter 6, “Picture Shapes,” in this book.
  5256. Combining Caps, Joins, Dashes, and Patterns
  5257.  
  5258. As mentioned in “Caps, Joins, Dashes and Patterns” on page 3-22, combining caps, joins, dashes, and patterns on the same shape causes some interesting interactions.
  5259. These elments interact differently in each of these three cases:
  5260. n    the shape does not have a dash but has one or more of the three other stylistic variations
  5261. n    the shape does have a dash but the gxClipDash dash attribute is not set
  5262. n    the shape does have a dash and the gxClipDash dash attribute is set
  5263. When a shape has a cap and a join, QuickDraw GX adds the caps to the beginnings and ends of the shape’s contours, and adds the joins to the other on-curve control points of the shape’s contours. If the shape also has a pattern, QuickDraw GX draws this pattern throughout the shape’s contours as well as the shape’s caps and joins. The sample function in Listing 3-21 creates an angle shape with a round cap, a square join, and a very small square pattern.
  5264. Listing 3-21    Combining a cap, join, and pattern
  5265.  
  5266. gxShape CapJoinPattern()
  5267. {
  5268.     gxShape             anAngleShape, aRoundCap, aSquareJoin, aSquarePattern;
  5269.  
  5270.     long             angleGeometry[] = {1, /* number of contours */
  5271.                                         3, /* number of points */
  5272.                                         ff(100), ff(100),
  5273.                                         ff(200), ff(80), 
  5274.                                         ff(300), ff(100)};    
  5275.         
  5276.     long             diamondGeometry[] = {1, /* number of contours */
  5277.                                           4, /* number of points */
  5278.                                           ff(0), ff(50), 
  5279.                                           ff(10), fl(0),
  5280.                                           ff(0), -ff(50), 
  5281.                                           -ff(10), ff(0)};
  5282.     
  5283.     gxRectangle         circleBounds ={-fl(.75), -fl(.75), 
  5284.                                         fl(.75), fl(.75)};
  5285.     gxRectangle         smallSquareGeometry = {ff(0), ff(0), ff(1), ff(1)};
  5286.      gxCapRecord         theCapRecord;
  5287.      gxJoinRecord         theJoinRecord;
  5288.      gxPatternRecord     thePatternRecord;
  5289.     
  5290.    /* Create the gxShape to be capped, joined, and patterned. */
  5291.     anAngleShape = GXNewPolygons((gxPolygons *) angleGeometry);
  5292.     GXSetShapeFill(anAngleShape, gxOpenFrameFill);
  5293.     GXSetShapePen(anAngleShape, ff(50));
  5294.     
  5295.     /* Create the round cap and cap the shape. */
  5296.     aRoundCap = NewArc(&circleBounds, ff(0), ff(360), false);
  5297.     GXSetShapeFill(aRoundCap, gxSolidFill);
  5298.     GXReverseShape(aRoundCap, 0); /* workaround */
  5299.     theCapRecord.startCap = aRoundCap;
  5300.     theCapRecord.endCap = aRoundCap;
  5301.     theCapRecord.attributes = gxNoAttributes;
  5302.     GXSetShapeCap(anAngleShape, &theCapRecord);
  5303.     GXDisposeShape(aRoundCap);
  5304.  
  5305.    /* Create the square join and join the shape. */
  5306.     aSquareJoin = GXNewRectangle(&circleBounds);
  5307.     GXSetShapeFill(aSquareJoin, gxSolidFill);
  5308.     GXReverseShape(aSquareJoin, 0); /* workaround */
  5309.     theJoinRecord.attributes = gxNoAttributes;
  5310.     theJoinRecord.join = aSquareJoin;
  5311.     theJoinRecord.miter = 0; 
  5312.     GXSetShapeJoin(anAngleShape, &theJoinRecord);
  5313.     GXDisposeShape(aSquareJoin);
  5314.  
  5315.     /* Create the small square pattern and pattern the shape. */
  5316.     aSquarePattern = GXNewRectangle(&smallSquareGeometry);
  5317.     GXSetShapeFill(aSquarePattern, gxSolidFill);
  5318.     thePatternRecord.attributes = gxNoAttributes;
  5319.     thePatternRecord.pattern = aSquarePattern;
  5320.     thePatternRecord.u.x = ff(0);
  5321.     thePatternRecord.u.y = ff(2);
  5322.     thePatternRecord.v.x = ff(2);
  5323.     thePatternRecord.v.y = ff(0);
  5324.     GXSetShapePattern(anAngleShape, &thePatternRecord);
  5325.     GXDisposeShape(aSquarePattern);
  5326.     
  5327.     GXDrawShape(anAngleShape);
  5328. }
  5329. The result of this function is shown in Figure 3-79.
  5330. Figure 3-79    Angle shape with cap, join, and pattern
  5331.  
  5332. The second case of cap, join, dash, and pattern interaction is when the shape has a dash but the gxClipDash dash attribute is not set. In this case, QuickDraw GX ignores the caps and joins of the shape. However, QuickDraw GX does draw the pattern throughout the dashes.
  5333. For example, if you add the following declarations at the appropriate places in the previous example:
  5334. gxShape aDiamondDash;
  5335. long             diamondGeometry[] = {1, /* number of contours */
  5336.                                        4, /* number of points */
  5337.                                        ff(0), ff(50), 
  5338.                                        ff(10), fl(0),
  5339.                                        ff(0), -ff(50), 
  5340.                                        -ff(10), ff(0)};     
  5341. gxDashRecord         theDashRecord;
  5342. and you add the following code to create a diamond-shaped dash:
  5343. /* Create the diamond dash and dash the shape. */
  5344. aDiamondDash = GXNewPolygons((gxPolygons *) diamondGeometry);
  5345. GXSetShapeFill(aDiamondDash, gxEvenOddFill);
  5346. theDashRecord.attributes = gxNoAttributes;  
  5347. theDashRecord.dash = aDiamondDash;
  5348. theDashRecord.advance = ff(40); 
  5349. theDashRecord.phase = 0; 
  5350. theDashRecord.scale = ff(50); 
  5351. GXSetShapeDash(anAngleShape, &theDashRecord);
  5352. GXDisposeShape(aDiamondDash);
  5353. the resulting shape will appear as depicted in Figure 3-80.
  5354. Figure 3-80    Shape with dash and pattern; caps and join ignored
  5355.  
  5356. The third case of cap, join, dash, and pattern interaction is when the shape has a dash and the gxClipDash dash attribute is set. In this case, QuickDraw GX adds the cap and the join shapes to the clip shape used to clip the dashes. Patterns are not allowed in this case, so if you add the following line to the previous example:
  5357. theDashRecord.attributes = gxClipDash;  
  5358. you must comment out this line:
  5359. /* GXSetShapePattern(anAngleShape, &thePatternRecord); */
  5360. which ensures that no pattern is set for the shape.
  5361. In this case, the resulting shape is drawn as shown in Figure 3-81.
  5362. Figure 3-81    Shape with cap, join, dash, and the gxClipDash dash attribute set
  5363.  
  5364. Notice that the dashes (which are now solid because there is no pattern) are clipped to the thick contours of the angle shape. However, at the ends and at the corner more of the dashes show because the cap shapes and the join shape are added to the clip shape used to clip the dashes.
  5365.  
  5366. Geometric Styles Reference
  5367.  
  5368. Each QuickDraw GX shape includes a shape object, a style object, an ink object, and a transform object. This section describes the data types and functions that are specific to style objects. 
  5369. The “Data Types” section shows the type definition for the style object, and the structure and enumeration definitions used for five of the properties of style objects: the style attributes, the caps, the join, the dash, and the pattern.
  5370. The “Functions” section describes fuctions that manipulate the geometric style properties: the style attributes, the curve error, the pen width, the caps, the join, the dash, and the pattern. These properties allow you to apply stylistic variations to geometric shapes.
  5371. For information regarding creating and manipulating style objects themselves, or manipulating their tags and owner counts, see the chapter “Style Objects” in Inside Macintosh: QuickDraw GX Objects.
  5372. For information regarding the typographic style properties—for example, the font, font size, and text face—see the chapter “Typographic Styles” of Inside Macintosh: QuickDraw GX Typography.
  5373. Constants and Data Types
  5374.  
  5375. This section describes the data types that you use to provide information about and to retrieve information from style objects.
  5376. You use the gxStyle data type when referring to a style object. 
  5377. You use the gxStyleAttributes enumeration when getting and setting individual flags of the attributes property of a style object.
  5378. You use the gxCapRecord structure and the gxCapAttributes enumeration when getting and setting the start cap and end cap of a shape.
  5379. You use the gxJoinRecord structure and the gxJoinAttributes enumeration when getting and setting the corner join of a shape.
  5380. You use the gxDashRecord structure and the gxDashAttributes enumeration when getting and setting a shape’s dashes.
  5381. You use the gxPatternRecord structure and the gxPatternAttributes enumeration when getting and setting a shape’s pattern.
  5382. Style Objects
  5383.  
  5384. As with all QuickDraw GX objects, the structure and content of style objects are private. To obtain information about a style object, or to alter information in a style object, you must pass a reference to the style object to a QuickDraw GX function. (Actually, QuickDraw GX provides two sets of functions for style object access: one set requires that you pass a reference to the style object itself; the other set allows you to pass a reference to the shape that references the style object.)
  5385. QuickDraw GX does not use handles to locate objects. Instead, it uses reference values. You identify a style object by using a style reference. To allow type checking, QuickDraw GX defines style references as pointers to structures:
  5386. typedef struct gxPrivateStyleRecord *gxStyle;
  5387. Style objects have owner counts, tags, typographic style properties, and seven geometric style properties. The owner count and tags properties are described in Inside Macintosh: QuickDraw GX Objects. The typographic style properties are described in Inside Macintosh: QuickDraw GX Typography. The geometric style properties are listed here:
  5388. n    Style attributes. This property is a group of flags that modify the behavior of the style object. In particular, these flags allow you to specify how QuickDraw GX places the pen with respect to a shape’s geometry and whether the shape should be constrained to a grid when drawn. The next section, “Style Attributes,” describes the style attribute flags, and “Getting and Setting Style Attributes” on page 3-102 describes the functions you can use to examine or alter style attribute flags.
  5389. n    Curve error. This property specifies the allowable amount of error when QuickDraw GX converts a path shape into a polygon shape. It also specifies how far apart geometric points must be for QuickDraw GX to consider them separate points when reducing or simplifying a shape. 
  5390. n    Pen width. This property specifies the thickness of the pen QuickDraw GX uses to draw the contours of a shape. “The Geometric Pen” on page 3-15 describes how QuickDraw GX uses the pen when drawing, and “Getting and Setting the Pen Width” on page 3-112 describes the functions you can use to examine or alter the pen width.
  5391. n    Caps. This property specifies what QuickDraw GX should draw at the start and the end of a shape’s contours. The section “Caps” on page 3-23 describes start and end caps, the sections “Cap Record Structure” on page 3-94 and “Cap Attributes” on page 3-95 discuss the data types you use to describe start and end caps, and the section “Getting and Setting Start Caps and End Caps” on page 3-116 describes the functions you can use to examine or alter a shape’s start and end caps.
  5392. n    Join. This property specifies what QuickDraw GX draws at the corners of a shape’s geometry. The section “Joins” on page 3-25 describes corner joins, the sections “Join Record Structure” on page 3-95 and “Join Attributes” on page 3-96 discuss the data types you use to describe corner joins, and the section “Getting and Setting Joins” on page 3-121 describes the functions you can use to examine or alter a shape’s corner joins.
  5393. n    Dash. This property specifies how QuickDraw GX should dash the contours of a shape. The section “Dashes” on page 3-27 describes dashes, the sections “Dash Record Structure” on page 3-97 and “Dash Attributes” on page 3-98 discuss the data types you use to describe dashes, and the section “Getting and Setting Dashes” on page 3-126 describes the functions you can use to examine or alter a shape’s dashes.
  5394. n    Pattern. This property specifies how QuickDraw GX should fill the geometry of a shape. The section “Patterns” on page 3-31 describes patterns, the sections “Pattern Record Structure” on page 3-99 and “Pattern Attributes” on page 3-100 discuss the data types you use to describe patterns, and the section “Getting and Setting Patterns” on page 3-132 describes the functions you can use to examine or alter a shape’s pattern.
  5395. Style Attributes
  5396.  
  5397. Each style object has a set of style attributes, which are a group of flags that modify the behavior of the style object. In particular, these flags allow you to specify how QuickDraw GX places the pen with respect to a shape’s geometry and whether the shape should be constrained to a grid. These flags are defined in the gxStyleAttributes enumeration:
  5398. enum gxStyleAttributes {
  5399.     gxCenterFrameStyle                            = 0,              /* center the pen on contour */
  5400.     gxSourceGridStyle                            = 0x0001,              /* constrain to source grid */
  5401.     gxDeviceGridStyle                            = 0x0002,              /* constrain to device grid */
  5402.     gxInsideFrameStyle                            = 0x0004,              /* place pen inside contour */
  5403.     gxOutsideFrameStyle                            = 0x0008,              /* place pen outside contour */
  5404.     gxAutoInsetStyle                            = 0x0010              /* don’t assume right is in */
  5405. };
  5406. typedef long gxStyleAttribute;
  5407. Flag descriptions
  5408. gxCenterFrameStyle
  5409. Indicates that QuickDraw GX should center the geometric pen along the shape’s contours. 
  5410. gxSourceGridStyle
  5411. Constrains the geometric points of the shape in geometry space. When drawing a shape whose style object has this flag set, QuickDraw GX moves each geometric point of the shape’s geometry to the closest integral position before applying the shape’s style and transform. (Note that the original geometric points are unchanged; this operation occurs only as the shape is being drawn.) See “Grids” beginning on page 3-21 for more information.
  5412. gxDeviceGridStyle
  5413. Constrains the geometric points of the shape in device space. When drawing a shape whose style object has this flag set, QuickDraw GX moves the shape’s geometric points, after applying the shape’s style and transform, to the closest integral position (that is, pixel position) in the device space. (Note that the original geometric points are unchanged; this operation occurs only as the shape is being drawn.) See “Grids” beginning on page 3-21 for more information.
  5414. gxInsideFrameStyle
  5415. Indicates that QuickDraw GX should position the pen along the inside of the shape’s contours. By default, QuickDraw GX uses the direction of a contour to determine which side is the inside; the right side of acontour is considered the inside. 
  5416. gxOutsideFrameStyle
  5417. Indicates that QuickDraw GX should place the pen along the outside of the shape’s contours. By default, QuickDraw GX uses the direction of a contour to determine which side is the inside; the left side of a contour is considered the outside.
  5418. gxAutoInsetStyle    Alters the default definition of the inside and outside of a contour. When this flag is not set, QuickDraw GX assumes the right side of a contour is the inside and the left side of a contour is the outside (which provides the correct behavior for TrueType fonts). When the gxAutoInsetStyle flag is set, QuickDraw GX finds the true inside of each contour, regardless of the contour direction.
  5419. Setting the gxInsideFrameStyle and gxOutsideFrameStyle style attributes results in the inconsistent_parameters error.
  5420. See “Grids” on page 3-21 for details about the algorithm QuickDraw GX uses to constrain the geometric points to grid. See “Manipulating Pen Width and Placement” on page 3-48 for examples of pen placement.
  5421. Cap Record Structure
  5422.  
  5423. QuickDraw GX allows you to specify what to draw at the start and at the end of a shape’s contours. In particular, you may specify a start cap for any point shape, and you may specify a start cap and an end cap for any line, curve, polygon, or path shape that has an gxOpenFrameFill shape fill.
  5424. QuickDraw GX uses the cap property of a shape’s style object to store information about the start cap and end cap of the shape. 
  5425. You use the cap record structure when specifying cap information (using the GXSetStyleCap or GXSetShapeCap functions) and when retrieving cap information (using the GXGetStyleCap or GXGetShapeCap functions).
  5426. The cap record structure is defined byt the gxCapRecord data type:
  5427. struct gxCapRecord {
  5428.     gxCapAttribute                    attributes;                /* modifies behavior of caps */
  5429.     gxShape                    startCap;                /* shape to use at contour starts */
  5430.     gxShape                    endCap;                /* shape to use at contour ends */
  5431. };
  5432. Field descriptions
  5433. attributes    Modifies the behavior of the caps. The next section, “Cap Attributes,”, describes the gxCapAttribute flags in detail.
  5434. startCap    Specifies what the start cap should look like. You must use shapes in their primitive form for the start cap shape; therefore, you can not use text, layout, bitmap, or picture shapes. 
  5435.     QuickDraw GX considers only the geometric properties (the shape type, the shape fill, and the shape geometry) of the shape specified by the startCap field. QuickDraw GX ignores the owner count, shape tags, and shape attributes properties and the style, ink, and transform objects of the start cap shape.
  5436. endCap    Specifies what the start cap should look like. You must use shapes in their primitive form for the endCap shape; therefore, you can not use text, layout, bitmap, or picture shapes. 
  5437.     QuickDraw GX considers only the geometric properties (the shape type, the shape fill, and the shape geometry) of the shape specified by the endCap field. QuickDraw GX ignores the owner count, shape tags, and shape attributes properties and the style, ink, and transform objects of the end cap shape.
  5438. See “Adding Caps to a Shape” on page 3-53 for examples of caps.
  5439. Cap Attributes
  5440.  
  5441. Each cap record structure contains a set of flags that modify the way a shape is capped. These flags are defined in the gxCapAttributes enumeration:
  5442. enum gxCapAttributes {
  5443.     gxLevelStartCap                    = 0x0001;                /* suppress start cap rotation */
  5444.     gxLevelEndCap                    = 0x0002;                /* suppress end cap rotation */
  5445. };
  5446. typedef long gxCapAttribute;
  5447. Flag descriptions
  5448. gxLevelStartCap
  5449. Suppresses rotation of the start cap shape. When you set this flag, QuickDraw GX does not rotate the start cap shape to match the slope of the capped contour. Instead, QuickDraw GX places the start cap shape onto the start of the capped contour with the exact orientation specified by the start cap shape’s geometry.
  5450. gxLevelEndCap    Suppresses rotation of the end cap shape. When you set this flag, QuickDraw GX does not rotate the end cap shape to match the slope of the capped contour. Instead, QuickDraw GX places the end cap shape onto the start of the capped contour with the exact orientation specified by the end cap shape’s geometry.
  5451. Join Record Structure
  5452.  
  5453. QuickDraw GX allows you to specify a join shape to be drawn at the corners of another shape’s contours. In particular, you may specify a join shape for any rectangle, polygon, or path shape that has an open-frame shape fill or closed-frame shape fill. 
  5454. n    For shapes with the closed-frame shape fill, QuickDraw GX draws the specified join shape at every on-curve geometric point of each contour.
  5455. n    For shapes with the open-frame shape fill, QuickDraw GX draws the specified join shape at every on-curve geometric point between the first point and the last point of each contour.
  5456. QuickDraw GX uses the join property of a shape’s style object to store information about the join of the shape. 
  5457. You use the join record structure when specifying join information (using the GXSetStyleJoin or GXSetShapeJoin functions) and when retrieving join information (using the GXGetStyleJoin or GXGetShapeJoin functions).
  5458. The join record structure is defined by the gxJoinRecord data type:
  5459. struct gxJoinRecord {
  5460.     gxJoinAttribute                    attributes;                /* modifies behavior of joins */
  5461.     gxShape                    join;                /* shape to use at corners */
  5462.     fixed                    miter;                /* limits size of sharp joins */
  5463. };
  5464. Field descriptions
  5465. attributes    Allows you to specify a level join, or to specify one of two standard types of joins: sharp joins and curve joins. The next section, “Join Attributes,”, describes the gxJoinAttribute flags in detail.
  5466. join    Specifies what the join should look like. You must use shapes in their primitive form for the join shape; therefore, you cannot use text, layout, bitmap, or picture shapes. 
  5467.     QuickDraw GX considers only the geometric properties (the shape type, the shape fill, and the shape geometry) of the shape specified by the join field. QuickDraw GX ignores the owner count, shape tags, and shape attributes properties and the style, ink, and transform objects of the join shape.
  5468.     You set this field to nil when you want to specify a standard join: a sharp join or curve join.
  5469. miter    Used to truncate sharp joins. See the next section, “Join Attributes,” for more information about sharp joins.
  5470. See “Adding Joins to a Shape” on page 3-58 and “Adding Standard Joins to a Shape” on page 3-61 for examples of joins.
  5471. Join Attributes
  5472.  
  5473. Each join record structure contains a set of flags that allow you to specify level joins, sharp joins, and curve joins. These flags are defined in the gxJoinAttributes enumeration:
  5474. enum gxJoinAttributes {
  5475.     gxSharpJoin            = 0x0000,                /* use default sharp joins */
  5476.     gxCurveJoin            = 0x0001,                /* use default curved joins */
  5477.     gxLevelJoin            = 0x0002                /* suppress join gxShape rotation */
  5478. };
  5479. typedef long gxJoinAttribute;
  5480. Flag descriptions
  5481. gxSharpJoin    Indicates that QuickDraw GX should continue the outside edges of the corners of the joined shape until they meet at a point. You can use the miter field of the gxJoinRecord structure to limit the size of a sharp join for very sharp corners. 
  5482. gxCurveJoin    Indicates that QuickDraw GX should connect the outside edges of the corners of the joined shape with a circular curve. 
  5483. gxLevelJoin    Suppresses rotation of the shape specifed by the join field of the gxJoinRecord structure. When you set this flag, QuickDraw GX does not rotate the join shape to match the mid-angle of the joined corner. Instead, QuickDraw GX places the join shape onto the joined corner with the exact orientation specified by the geoemtry of the join shape.
  5484. QuickDraw GX draws a sharp join or a curve join for every corners of every geometric shape; you may additionally specify a join shape to be added to a shape’s corner using the join field of the join record structure.
  5485. The miter field of the join record structure allows you to limit the size of sharp joins, which is particularly useful if the joined corner is very sharp. In the miter field, you specify the maximum distance between the actual corner (as specified by the joined shape’s geometry) and the tip of the sharp corner as drawn. 
  5486. See “Adding Standard Joins to a Shape” on page 3-61 for an example of a standard join.
  5487. Dash Record Structure
  5488.  
  5489. With QuickDraw GX, you can specify that certain shapes should be drawn with dashed, instead of solid, contours. In particular, you may specify a dash for any line, curve, rectangle, polygon, or path shape that has open-frame shape fill or a closed-frame shape fill. 
  5490. QuickDraw GX uses the dash property of a shape’s style object to store information about how to dash the shape. 
  5491. You use the dash record structure when specifying dash information (using the GXSetStyleDash or GXSetShapeDash functions) and when retrieving dash information (using the GXGetStyleDash or GXGetShapeDash functions).
  5492. The dash record structure is defined by the gxDashRecord data type:
  5493. struct gxDashRecord {
  5494.     gxDashAttribute                    attributes; /* modifies behavior of dashes */
  5495.     gxShape                     dash;                /* gxShape used for dashing */
  5496.     fixed                     advance;                /* distance between dashes */
  5497.     fract                     phase;                /* start offset into the gxPath */
  5498.     fixed                     scale;                /* height of dash (mapped to pen) */
  5499. };
  5500. Field descriptions
  5501. attributes    Modifies the behavior of the dashes. The next section, “Dash Attributes,”, describes the gxDashAttribute flags in detail.
  5502. dash    Specifies what the dashes should look like. You must use shapes in their primitive form for the dash shape; therefore, you can not use text, layout, bitmap, or picture shapes.
  5503.     QuickDraw GX considers only the geometric properties (the shape type, the shape fill, and the shape geometry) of the shape specified by the dash field. QuickDraw GX ignores the owner count, shape tags, and shape attributes properties and the style, ink, and transform objects of the dash shape.
  5504. advance    Indicates the distance between dashes. This fixed-point value is the distance along the contours of the dashed shape between the beginning of a dash and the beginning of the following dash. The value must be greater than 0.
  5505. phase    Specifies the initial placement of a dash. This value can vary between –2.0 and 2.0. A value of 0 indicates that the dash shape should not be offset—that is, the start of the first dash shape should be aligned with the start of the contour. A value greater than 0 indicates that the first dash along the contour should begin a certain percentage into the dash shape. A value of 1.0 indicates that the dashes should be shifted exactly one advance width—this value is equivalent to specifying a value of 0. Values greater than 1.0 are equivalent to their fractional part.
  5506. scale    Specifies the scaling of the dash shape. QuickDraw GX uses this value to scale the dash shape in one dimension—perpendicularly to the contour being dashed. The dash scale is divided out of the dashed contours width: decreasing the scale has the effect of thickening the dashed contour.
  5507. See “Dashing a Shape” on page 3-63 for examples of dashing.
  5508. Dash Attributes
  5509.  
  5510. Each dash record structure contains a set of flags that modify the way a shape is dashed. These flags are defined in the gxDashAttributes enumeration:
  5511. enum gxDashAttributes {
  5512.     gxBendDash                        = 0x0001;                  /* distorts gxShape in 1 dimension */
  5513.     gxBreakDash                        = 0x0002;                   /* places dash contours separately */
  5514.     gxClipDash                        = 0x0004;                  /* clips dashes to pen width */
  5515.     gxLevelDash                        = 0x0008;                  /* suppresses dash rotation */
  5516.     gxAutoAdvanceDash = 0x0010;                                          /* adjusts advances to fit contour */
  5517. };
  5518. typedef long gxDashAttribute;
  5519. Flag descriptions
  5520. gxBendDash    Distorts the dash shape to match the contour being dashed. A dash may have the gxBendDash attribute only when the dashed shape’s pen width is zero, indicating hairline contours. (Any other pen width results in an error condition.) When the gxBendDash property is set, QuickDraw GX maps the dash shape onto the x-axis (so that it becomes one-dimensional) and bends this flattened dash shape along the contours of the shape being dashed.
  5521. gxBreakDash    Indicates that QuickDraw GX should rotate and place each contour of the dash shape separately. When this attribute is set, QuickDraw GX calculates the center point of each contour of the dash shape and rotates and centers it appropriately along the contour of the shape being dashed. See Figure 3-26 on page 3-30 for an example.
  5522. gxClipDash    Indicates that QuickDraw GX should clip the dashes to the pen width of the dashed shape. See Figure 3-25 on page 3-29 for an example. This attribute causes dashes to have some complicated interactions with caps and joins. See the section “Interactions Between Caps, Joins, Dashes, and Patterns” on page 3-33 for more information.
  5523. gxLevelDash    Suppresses rotation of the dash shape. When this attribute is set, QuickDraw GX does not rotate the dash shape to match the slope of the dashed shape’s contours. Instead, QuickDraw GX places the dash shape onto the contours of the dashed shape with the exact orientation specified by the geometry of the dash shape.
  5524. gxAutoAdvanceDash
  5525. Adjusts the dash advance so that a whole multiple of dash shapes fit each contour. 
  5526. These sections include examples of dashing and of using dash attributes:
  5527. n    “Dashing a Shape” on page 3-63
  5528. n    “Adjusting Dashes to Fit Contours” on page 3-67
  5529. n    “Breaking and Bending Dashes” on page 3-71
  5530. Pattern Record Structure
  5531.  
  5532. With QuickDraw GX, you can specify that certain shapes be patterned. For shapes with solid shape fills, QuickDraw GX fills the shape by repeating a pattern shape that you specify over a grid that you specify.
  5533. You can also pattern shapes with framed shape fills. For example, imagine a rectangle shape with the closed-frame shape fill and a pen width of 20. If you patterned this rectangle, QuickDraw GX would fill the frame of the rectangle with the pattern. See the section “Adding a Pattern to a Shape” on page 3-81 for examples.
  5534. QuickDraw GX uses the pattern property of a shape’s style object to store information about how to pattern the shape. 
  5535. You use the pattern record structure when specifying pattern information (using the GXSetStylePattern or GXSetShapePattern functions) and when retrieving pattern information (using the GXGetStylePattern or GXGetShapePattern functions).
  5536. The pattern record structure is defined by the gxPatternRecord data type:
  5537. struct gxPatternRecord {
  5538.     gxPatternAttribute                         attributes;                 /* modifier flags */
  5539.     gxShape                         pattern;                 /* shape to use as pattern */
  5540.     gxPoint                         u;                 /* vector for pattern grid */
  5541.     gxPoint                         v;                 /* vector for pattern grid */
  5542. };
  5543. Field descriptions
  5544. attributes    Modifies the behavior of the pattern. The next section, “Pattern Attributes,” describes the gxPatternAttribute flags in detail.
  5545. pattern    Specifies the shape that makes up the pattern. You must use shapes in their primitive form for the pattern shape; therefore, you can not use text, layout, or picture shapes, although you can use bitmap shapes for patterns.
  5546.     QuickDraw GX considers only the geometric properties (the shape type, the shape fill, and the shape geometry) of the shape specified by the pattern field. QuickDraw GX ignores the owner count, shape tags, and shape attributes properties and the style, ink, and transform objects of the pattern shape.
  5547. u    One of a pair of vectors that determine how QuickDraw GX places the pattern shape. This field, along with the v field, defines the pattern grid. 
  5548. v    The other of the pair of vectors that describe how QuickDraw GX places the pattern shape. This field, along with the u field, defines the pattern grid. 
  5549. The u and v fields together form a pair of vectors that define the pattern grid, which determines where QuickDraw GX places the pattern shape. The vectors define a grid of parallelograms and QuickDraw GX draws a pattern shape at every intersection in this grid. 
  5550. The vectors specified by the u and v fields do not need to be any order, but they must point in different directions—that is, they may not lie on the same line. If you specify u and v vectors that are parallel, a pattern_lattice_out_of_range error results.
  5551. Optimization Note
  5552. QuickDraw GX draws bitmap patterns very quickly—that is, nearly as fast as a nonpatterned fill—if the u and v vectors place the patterns in a rectangular grid the size of the bitmap.u
  5553. See “Patterns” on page 3-31 for an example of a pattern grid, and “Adding a Pattern to a Shape” on page 3-81 for an example of patterns.
  5554. Pattern Attributes
  5555.  
  5556. Each pattern record structure contains a set of flags that modify the way a shape is patterned. These flags are defined in the gxPatternAttributes enumeration:
  5557. enum gxPatternAttributes {
  5558.     gxPortAlignPattern = 0x0001, /* align pattern with device */
  5559.     gxPortMapPattern   = 0x0002  /* suppress mapping of pattern */
  5560. };
  5561. typedef long gxPatternAttribute;
  5562. Flag descriptions
  5563. gxPortAlignPattern
  5564. Indicates that QuickDraw GX should align the pattern shapes with the view device instead of the patterned shape. When this attribute is set, the pattern does not move when the patterned shape moves. Instead, the position of the pattern stays constant with respect to the view device. In effect, the patterned shape allows you to see through to a constant background covered by the pattern shape. 
  5565. gxPortMapPattern
  5566.     Indicates that mappings in the patterned shape’s transform affect the patterned shape but do not affect the pattern. As an example, imagine that the transform of the patterned shape specifies that the patterned shape be scaled up by a factor of 2. If the gxPortMapPattern attribute is not set, then the pattern itself is magnified as well as the patterned shape. If this attribute is set, then the pattern stays the same size, but the patterned shape shows more of the pattern.
  5567. See the section “Patterns” on page 3-31 for an example of these attributes.
  5568. Functions
  5569.  
  5570. This section describes the functions avaliable for manipulating a style object’s geometric properties:
  5571. n    the style attributes
  5572. n    the curve error
  5573. n    the pen width
  5574. n    the caps
  5575. n    the join
  5576. n    the dash
  5577. n    the pattern
  5578. These properties together determine the stylistic variations applied to the frame and the area of a shape when drawn. 
  5579. For information about creating, disposing of, copying, and comparing style objects as well as information about manipulating style tags and style owner counts, see Inside Macintosh: QuickDraw GX Objects.
  5580. For information about the typographic style properties, such as font, font size, and text face, see Inside Macintosh: QuickDraw GX Typography.
  5581. In general, there are two types of functions that manipulate the properties of style objects:
  5582. n    Functions that require you to provide a reference to the style object itself.
  5583. n    Functions that allow you to provide a reference to a shape and affect the style object associated with that shape.
  5584. The section “Associating Styles With Shapes” on page 3-36 provides an example of both of these types of functions and compares their results.
  5585. Both types of functions are described in this reference section.
  5586. Getting and Setting Style Attributes
  5587.  
  5588. The style attributes are a set of flags that modify the behavior of the style object. In particular, these flags allow you to specify how QuickDraw GX places the geoemtric pen with respect to a shape’s geometry and whether the shape should be constrained to a grid. 
  5589. For a description of the style attributes, see the section “Style Attributes” on page 3-92.
  5590. You can use the GXGetStyleAttributes function to find the style attributes of an existing style and the GXSetStyleAttributes function to set the style attributes of a style.
  5591. The GXGetShapeStyleAttributes and GXSetShapeStyleAttributes functions provide a way to determine and change the curve error of a style object associated with a particular shape.
  5592. GXGetStyleAttributes
  5593.  
  5594. You can use the GXGetStyleAttributes function to determine which style attributes are set for a particular style object.
  5595. gxStyleAttribute GXGetStyleAttributes(gxStyle source);
  5596. source    A reference to the style object whose style attributes you want to determine.
  5597. function result    The style attributes associated with the source style object.
  5598. DESCRIPTION
  5599. The GXGetStyleAttributes function returns as its function result the style attributes of the style specified by the source parameter.
  5600. As an example, to examine the gxSourceGridStyle flag of a style object referenced by the variable source, you could use this code:
  5601. if (GXGetStyleAttributes(source) & gxSourceGridStyle) {
  5602.     /* style has gxSourceGridStyle attribute set */
  5603. }
  5604. However, since the gxCenterFrameStyle attribute is set only if both the gxInsideFrameStyle and the gxOutsideFrameStyle attributes are clear, you need this code to test for a centered frame style:
  5605. if (GXGetStyleAttributes(source)     & 
  5606.     (gxInsideFrameStyle | gxOutsideFrameStyle) ==             
  5607.     gxCenterFrameStyle) {
  5608.     /* gxStyle has gxCenterFrameStyle attribute set */
  5609. }
  5610. ERRORS, WARNINGS, AND NOTICES
  5611. Errors    
  5612. out_of_memory    
  5613. style_is_nil    
  5614.  
  5615. SEE ALSO
  5616. For a discussion of style attributes, see “Style Attributes” on page 3-92.
  5617. For an example of pen placement, see “Manipulating Pen Width and Placement” on page 3-48.
  5618. For an example of constraining shapes to grids, see “Constraining Shape Geometries to Grids” on page 3-39 and “Constraining Shapes to Device Grids” on page 3-41.
  5619. To examine the style attributes of a style object associated with a particular shape, use the GXGetShapeStyleAttributes function, which is described on page 3-105.
  5620. To alter the style attributes of a style object, use the GXSetStyleAttributes function, which is described in the next section.
  5621. To alter the style attributes of a style object associated with a particular shape, use the GXSetShapeStyleAttributes function, which is described on page 3-106.
  5622. GXSetStyleAttributes
  5623.  
  5624. You can use the GXSetStyleAttributes function to alter the style attributes for a particular style object.
  5625. void GXSetStyleAttributes(gxStyle target, 
  5626.                                   gxStyleAttribute attributes);
  5627. target    The style object whose attributes you want to alter.
  5628. attributes    The new set of attributes.
  5629. DESCRIPTION
  5630. The GXSetStyleAttributes function sets the style attributes of the style object specified by the target parameter to be the attributes specified in the attributes parameter.
  5631. You can use this function in combination with the GXGetStyleAttributes function to set or clear single style attributes. For example, to clear the gxSourceGridStyle attribute of a style object referenced by the variable target, you could use this line of C code:
  5632. GXSetStyleAttributes(target,
  5633.                    GXGetStyleAttributes(target & ~gxSourceGridStyle);
  5634. To set the gxSourceGridStyle attribute, you could use this line of code:
  5635. GXSetStyleAttributes(target,
  5636.                    GXGetStyleAttributes(target | gxSourceGridStyle);
  5637. To set the gxCenterFrameStyle attribute, you need to clear the gxInsideFrameStyle and gxOutsideFrameStyle attributes.
  5638. When you set a style’s attributes using this function, you are effectively changing the style attributes for all shapes that share the style.
  5639. ERRORS, WARNINGS, AND NOTICES
  5640. Errors    
  5641. out_of_memory    
  5642. style_is_nil    
  5643. inconsistent_parameters    
  5644. parameter_out_of_range    
  5645. Notices    
  5646. attributes_already_set    
  5647.  
  5648. SEE ALSO
  5649. For a discussion of style attributes, see “Style Attributes” on page 3-92.
  5650. For an example of pen placement, see “Manipulating Pen Width and Placement” on page 3-48.
  5651. For an example of constraining shapes to grids, see “Constraining Shape Geometries to Grids” on page 3-39 and “Constraining Shapes to Device Grids” on page 3-41.
  5652. To examine the style attributes of a style object, use the GXGetStyleAttributes function, which is described on page 3-102.
  5653. To examine the style attributes of a style object associated with a particular shape, use the GXGetShapeStyleAttributes function, which is described in the next section.
  5654. To alter the style attributes of a style object associated with a particular shape, use the GXSetShapeStyleAttributes function, which is described on page 3-106.
  5655. GXGetShapeStyleAttributes
  5656.  
  5657. You can use the GXGetShapeStyleAttributes function to determine which style attributes are set for the style object of a particular shape.
  5658. gxStyleAttribute GXGetShapeStyleAttributes(gxShape source);
  5659. source    A reference to the shape whose style attributes you want to determine.
  5660. function result    The style attributes of the source shape’s style object.
  5661. DESCRIPTION
  5662. The GXGetShapeStyleAttributes function returns as its function result the style attributes of the style object associated with the shape specified by the source parameter.
  5663. This function provides a convenient way to determine the style attributes of a shape without having to call the GXGetShapeStyle function to obtain a reference to the shape’s style object.
  5664. As an example, to examine the gxSourceGridStyle flag of a style object refeernced by the variable source, you could use this code:
  5665. if (GXGetShapeStyleAttributes(source) & gxSourceGridStyle) {
  5666.     /* gxStyle has gxSourceGridStyle attribute set */
  5667. }
  5668. However, since the gxCenterFrameStyle attribute is set only if both the gxInsideFrameStyle and the gxOutsideFrameStyle attributes are clear, you need this code to test for a centered frame style:
  5669. if (GXGetShapeStyleAttributes(source)     & 
  5670.     (gxInsideFrameStyle | gxOutsideFrameStyle) ==    gxCenterFrameStyle) {
  5671.     /* gxStyle has gxCenterFrameStyle attribute set */
  5672. }
  5673. ERRORS, WARNINGS, AND NOTICES
  5674. Errors    
  5675. out_of_memory    
  5676. shape_is_nil    
  5677. Notices (debugging version)    
  5678. notice    
  5679.  
  5680. SEE ALSO
  5681. For a discussion of style attributes, see “Style Attributes” on page 3-92.
  5682. For an example of pen placement, see “Manipulating Pen Width and Placement” on page 3-48.
  5683. For an example of constraining shapes to grids, see “Constraining Shape Geometries to Grids” on page 3-39 and “Constraining Shapes to Device Grids” on page 3-41.
  5684. To examine the style attributes of a style object, use the GXGetStyleAttributes function, which is described on page 3-102.
  5685. To alter the style attributes of a style object, use the GXSetStyleAttributes function, which is described on page 3-103.
  5686. To alter the style attributes of a style object associated with a particular shape, use the GXSetShapeStyleAttributes function, which is described in the next section.
  5687. GXSetShapeStyleAttributes
  5688.  
  5689. You can use the GXSetShapeStyleAttributes function to alter the style attributes of the style object associated with a particular shape.
  5690. void GXSetShapeStyleAttributes(gxShape target, 
  5691.                                         gxStyleAttribute attributes);
  5692. target    The shape whose style attributes you want to alter.
  5693. attributes    The new set of attributes.
  5694. DESCRIPTION
  5695. The GXSetShapeStyleAttributes function sets the style attributes of the style object associated with the shape specified by the target parameter.
  5696. If the target shape shares its style object with other shapes, this function makes a copy of the style object, sets the target shape to reference the copy, and changes the style attributes of the copy. (However, if the effect of this function would leave the style attributes unchanged, this function does not create a copy of the style object; instead, it posts a notice).
  5697. You can use this function in combination with the GXGetShapeStyleAttributes function to set or clear single style attributes. For example, to clear the gxSourceGridStyle attribute of a style object associated with a target shape, you could use this line of code:
  5698. GXSetShapeStyleAttributes(target,
  5699.             GXGetShapeStyleAttributes(target & ~gxSourceGridStyle);
  5700. To set the gxSourceGridStyle attribute, you could use this line of code:
  5701. GXSetShapeStyleAttributes(target,
  5702.              GXGetShapeStyleAttributes(target | gxSourceGridStyle);
  5703. ERRORS, WARNINGS, AND NOTICES
  5704. Errors    
  5705. out_of_memory    
  5706. style_is_nil    
  5707. inconsistent_parameters    
  5708. parameter_out_of_range    
  5709. Notices (debugging version)    
  5710. attributes_already_set    
  5711.  
  5712. SEE ALSO
  5713. For a discussion of style attributes, see “Style Attributes” on page 3-92.
  5714. For an example of pen placement, see “Manipulating Pen Width and Placement” on page 3-48.
  5715. For an example of constraining shapes to grids, see “Constraining Shape Geometries to Grids” on page 3-39 and “Constraining Shapes to Device Grids” on page 3-41.
  5716. To examine the style attributes of a style object, use the GXGetStyleAttributes function, which is described on page 3-102.
  5717. To examine the style attributes of a style object associated with a particular shape, use the GXGetShapeStyleAttributes function, which is described on page 3-105.
  5718. To alter the style attributes of a style object, use the GXSetStyleAttributes function, which is described on page 3-103.
  5719. Getting and Setting Curve Error
  5720.  
  5721. The curve error property of style objects specifies the allowable amount of error when QuickDraw GX converts a path shape into a polygon shape. It also specifies how far apart geometric points must be for QuickDraw GX to consider them separate points when performing geometric operations on shapes or reducing shapes. 
  5722. For example, when you call the GXInsetShape function on a tight curve, the resulting curve can require many more geometric points than the original curve. QuickDraw GX simplifies the resulting shape by removing geometric points that are within the shape’s curve error from another geometric point. 
  5723. You can use the GXGetStyleCurveError function to determine the curve error of a style object and the GXSetStyleCurveError function to change the curve error of a style object.
  5724. The GXGetShapeCurveError and GXSetShapeCurveError functions provide a way to determine and change the curve error of the style object associated with a particular shape.
  5725. GXGetStyleCurveError  
  5726.  
  5727. You can use the GXGetStyleCurveError function to determine the curve error of a style object.
  5728. fixed GXGetStyleCurveError(gxStyle source);
  5729. source    The style object whose curve error you want to determine.
  5730. function result    The curve error of the source style object.
  5731. DESCRIPTION
  5732. The GXGetStyleCurveError function returns as its function result the curve error of the style object specified by the source parameter.
  5733. When a path shape has a curve error of 0, QuickDraw GX does not approximate the path shape with a polygons shape when converting it to a polygon. Instead, QuickDraw GX simply removes off-curve control points, as shown in “Converting Paths to Polygons” on page 3-43.
  5734. ERRORS, WARNINGS, AND NOTICES
  5735. Errors    
  5736. out_of_memory    
  5737. style_is_nil    
  5738.  
  5739. SEE ALSO
  5740. For a discussion of curve error, see “Curve Error” on page 3-14.
  5741. For examples of curve error, see “Converting Paths to Polygons” on page 3-43 and “Using Curve Error When Reducing Shapes” on page 3-46.
  5742. To change the curve error of a style object, use the GXSetStyleCurveError function, which is described in the next section.
  5743. To examine the curve error of a style object associated with a particular shape, use the GXGetShapeCurveError function, which is described on page 3-110.
  5744. To change the curve error of a style object associated with a particular shape, use the GXSetShapeCurveError function, which is described on page 3-111.
  5745. GXSetStyleCurveError  
  5746.  
  5747. You can use the GXSetStyleCurveError function to change the curve error of a style object.
  5748. void GXSetStyleCurveError(gxStyle target, fixed error);
  5749. target    The style object whose curve error you want to change.
  5750. error    The new curve error.
  5751. DESCRIPTION
  5752. This routine sets the curve error of the style object specifed by the target parameter to be the fixed-point value specified by the error parameter.
  5753. When a path shape has a curve error of 0, QuickDraw GX does not approximate the path shape with a polygon shape when converting it to a polygon. Instead, QuickDraw GX simply removes off-curve control points, as shown in “Converting Paths to Polygons” on page 3-43.
  5754. A very small curve error may cause the GXSetShapeType function and certain geometric operations such as the GXInsetShape function to use inappropriate amounts of memory and time.
  5755. When you set a style’s curve error using this function, you are effectively changing the curve error for all shapes that share the style.
  5756. ERRORS, WARNINGS, AND NOTICES
  5757. Errors    
  5758. out_of_memory    
  5759. style_is_nil    
  5760. parameter_out_of_range    
  5761. Notices (debugging version)    
  5762. curve_error_already_set    
  5763.  
  5764. SEE ALSO
  5765. For a discussion of curve error, see “Curve Error” on page 3-14.
  5766. For examples of curve error, see “Converting Paths to Polygons” on page 3-43 and “Using Curve Error When Reducing Shapes” on page 3-46.
  5767. To determine the curve error of a style object, use the GXGetStyleCurveError function, which is described on page 3-110.
  5768. To examine the curve error of a style object associated with a particular shape, use the GXGetShapeCurveError function, which is described in the next section.
  5769. To change the curve error of a style object associated with a particular shape, use the GXSetShapeCurveError function, which is described on page 3-111.
  5770. GXGetShapeCurveError  
  5771.  
  5772. You can use the GXGetShapeCurveError function to determine the curve error of the style object associated with a particular shape.
  5773. fixed GXGetShapeCurveError(gxShape source);
  5774. source    The shape whose curve error you want to determine.
  5775. function result    The curve error of the style object associated with the source shape.
  5776. DESCRIPTION
  5777. The GXGetShapeCurveError function returns as its function result the curve error of the style object associated with the shape specified by the source parameter.
  5778. When a path shape has a curve error of 0, QuickDraw GX does not approximate the path shape with a polygon shape when converting it to a polygon. Instead, QuickDraw GX simply removes off-curve control points, as shown in “Converting Paths to Polygons” on page 3-43.
  5779. ERRORS, WARNINGS, AND NOTICES
  5780. Errors    
  5781. out_of_memory    
  5782. shape_is_nil    
  5783.  
  5784. SEE ALSO
  5785. For a discussion of curve error, see “Curve Error” on page 3-14.
  5786. For examples of curve error, see “Converting Paths to Polygons” on page 3-43 and “Using Curve Error When Reducing Shapes” on page 3-46.
  5787. To determine the curve error of a style object, use the GXGetStyleCurveError function, which is described on page 3-108.
  5788. To change the curve error of a style object, use the GXSetStyleCurveError function, which is described on page 3-109.
  5789. To change the curve error of a style object associated with a particular shape, use the GXSetShapeCurveError function, which is described in the next section.
  5790. GXSetShapeCurveError  
  5791.  
  5792. You can use the GXSetShapeCurveError function to change the curve error of the style object associated with a particular shape.
  5793. void GXSetShapeCurveError(gxShape target, fixed error);
  5794. target    The shape whose curve error you want to change.
  5795. error    The new curve error.
  5796. DESCRIPTION
  5797. The GXSetShapeCurveError function replaces the curve error of the style object associated with the shape specified by the source parameter with the value in the error parameter.
  5798. If the target shape shares its style object with other shapes, this function makes a copy of the style object, sets the target shape to reference the copy, and changes the curve error of the copy. (However, if the effect of this function would leave the curve error unchanged, this function does not create a copy of the style object; instead, it posts a notice.)
  5799. When the curve error is 0, QuickDraw GX does not approximate a path shape with a polygon shape when converting from a path to a polygon. Instead, QuickDraw GX simply removes off-curve control points, as shown in “Converting Paths to Polygons” on page 3-43.
  5800. ERRORS, WARNINGS, AND NOTICES
  5801. Errors    
  5802. out_of_memory    
  5803. shape_is_nil    
  5804. parameter_out_of_range    
  5805. Notices (debugging version)    
  5806. curve_error_already_set    
  5807.  
  5808. SEE ALSO
  5809. For a discussion of curve error, see “Curve Error” on page 3-14.
  5810. For examples of curve error, see “Converting Paths to Polygons” on page 3-43 and “Using Curve Error When Reducing Shapes” on page 3-46.
  5811. To determine the curve error of a style object, use the GXGetStyleCurveError function, which is described on page 3-108.
  5812. To change the curve error of a style object, use the GXSetStyleCurveError function, which is described on page 3-109.
  5813. To determine the curve error of a style object associated with a particular shape, use the GXGetShapeCurveError function, which is described on page 3-110.
  5814. Getting and Setting the Pen Width
  5815.  
  5816. The pen width property of a style object specifies the width at which QuickDraw GX should draw a shape’s contours. A pen width of 0 specifies a hairline. QuickDraw GX always draws hairlines at the resolution of the output device—one pixel wide. 
  5817. You can use the GXGetStylePen function to determine the pen width of a style object and the GXSetStylePen function to change the pen width of a style object.
  5818. The GXGetShapePen and GXSetShapePen functions provide a way to determine and change the pen width of the style object associated with a particular shape.
  5819. GXGetStylePen  
  5820.  
  5821. You can use the GXGetStylePen function to determine the pen width of a particular style object.
  5822. fixed GXGetStylePen(gxStyle source);
  5823. source    The style object whose pen width you want to determine.
  5824. function result    The pen width of the source style object.
  5825. DESCRIPTION
  5826. The GXGetStylePen function returns as its function result the pen width associated with the source style object.
  5827. A pen width of 0 indicates a hairline width; QuickDraw GX always draws hairlines one pixel wide.
  5828. ERRORS, WARNINGS, AND NOTICES
  5829. Errors    
  5830. out_of_memory    
  5831. style_is_nil    
  5832.  
  5833. SEE ALSO
  5834. For a discussion of the drawing pen, see “The Geometric Pen” on page 3-15.
  5835. For an example changing a shape’s pen width, see “Manipulating Pen Width and Placement” on page 3-48.
  5836. To change the pen width of a style object, use the GXSetStylePen function, which is described in the next section.
  5837. To determine the pen width of a style object associated with a particular shape, use the GXGetShapePen function, which is described on page 3-114.
  5838. To change the pen width of a style object associated with a particular shape, use the GXSetShapePen function, which is described on page 3-115.
  5839. GXSetStylePen  
  5840.  
  5841. You can use the GXSetStylePen function to change the pen width of a style object.
  5842. void GXSetStylePen(gxStyle target, fixed pen);
  5843. target    The style object whose pen width you want to change.
  5844. pen    The new pen width.
  5845. DESCRIPTION
  5846. The GXSetStylePen function sets the pen width of the style object specified by the target parameter to the value specified in the pen parameter.
  5847. A pen width of 0 indicates a hairline; QuickDraw GX always draws hairlines one pixel wide.
  5848. Remember that the pen parameter is specified as a fixed-point value. Very small diameters may cause all drawing to disappear, since a shape may fall between pixels:
  5849. GXSetStylePen(myStyle, 1);  /* set the pen width to 1/65536 */
  5850. GXSetStylePen(myStyle, ff(1));  /* set the pen width to 1.0 */
  5851. When you set the pen width using this function, you are effectively changing the pen width for all shapes that share the style.
  5852. ERRORS, WARNINGS, AND NOTICES
  5853. Errors    
  5854. out_of_memory    
  5855. style_is_nil    
  5856. parameter_out_of_range    
  5857. Notices (debugging version)    
  5858. pen_size_already_set    
  5859.  
  5860. SEE ALSO
  5861. For a discussion of the drawing pen, see “The Geometric Pen” on page 3-15.
  5862. For an example of changing a shape’s pen width, see “Manipulating Pen Width and Placement” on page 3-48.
  5863. To determine the pen width of a style object, use the GXGetStylePen function, which is described on page 3-112.
  5864. To determine the pen width of a style object associated with a particular shape, use the GXGetShapePen function, which is described in the next section.
  5865. To change the pen width of a style object associated with a particular shape, use the GXSetShapePen function, which is described on page 3-115.
  5866. GXGetShapePen  
  5867.  
  5868. You can use the GXGetShapePen function to determine the pen width of the style object associated with a particular shape.
  5869. fixed GXGetShapePen(gxShape source);
  5870. source    The shape whose pen width you want to determine.
  5871. function result    The pen width of the source shape’s style object.
  5872. DESCRIPTION
  5873. The GXGetShapePen function returns as its function result the pen width associated with the source shape’s style object.
  5874. ERRORS, WARNINGS, AND NOTICES
  5875. Errors    
  5876. out_of_memory    
  5877. shape_is_nil    
  5878.  
  5879. SEE ALSO
  5880. For a discussion of the drawing pen, see “The Geometric Pen” on page 3-15.
  5881. For an example of changing a shape’s pen width, see “Manipulating Pen Width and Placement” on page 3-48.
  5882. To determine the pen width of a style object, use the GXGetStylePen function, which is described on page 3-112.
  5883. To change the pen width of a style object, use the GXSetStylePen function, which is described on page 3-113.
  5884. To change the pen width of a style object associated with a particular shape, use the GXSetShapePen function, which is described in the next section.
  5885. GXSetShapePen  
  5886.  
  5887. You can use the GXSetShapePen function to change the pen width of the style object associated with a particular shape.
  5888. void GXSetShapePen(gxShape target, fixed pen);
  5889. target    The shape whose pen width you want to change.
  5890. pen    The new pen width.
  5891. DESCRIPTION
  5892. The GXSetShapePen function sets the pen width of the target shape’s style object to be the value specified in the pen parameter.
  5893. If the target shape shares its style object with other shapes, this function makes a copy of the style object, sets the target shape to reference the copy, and changes the pen width of the copy. (However, if the effect of this function would leave the pen width information unchanged, this function does not create a copy of the style object; instead, it posts a notice.)
  5894. A pen width of 0 indicates a hairline; QuickDraw GX always draws hairlines one pixel wide.
  5895. GXSetShapePen(myShape, 0);                                  /* set as thin as renderable */
  5896. Remember that the pen parameter is specified as a fixed-point value. Very small diameters may cause all drawing to disappear, since a shape may fall between pixels:
  5897. GXSetStylePen(myStyle, 1);  /* set the pen width to 1/65536 */
  5898. GXSetStylePen(myStyle, ff(1));  /* set the pen width to 1.0 */
  5899. ERRORS, WARNINGS, AND NOTICES
  5900. Errors    
  5901. out_of_memory    
  5902. shape_is_nil    
  5903. parameter_out_of_range    
  5904. Notices (debugging version)    
  5905. pen_size_already_set    
  5906.  
  5907. SEE ALSO
  5908. For a discussion of the drawing pen, see “The Geometric Pen” on page 3-15.
  5909. For an example of changing a shape’s pen width, see “Manipulating Pen Width and Placement” on page 3-48.
  5910. To determine the pen width of a style object, use the GXGetStylePen function, which is described on page 3-112.
  5911. To change the pen width of a style object, use the GXSetStylePen function, which is described on page 3-113.
  5912. To determine the pen width of a style object associated with a particular shape, use the GXGetShapePen function, which is described on page 3-114.
  5913. Getting and Setting Start Caps and End Caps
  5914.  
  5915. QuickDraw GX allows you to specify what to draw at the start and at the end of a shape’s contours. In particular, you may specify a start cap for any point shape, and you may specify a start cap and an end cap for any line, curve, polygon, or path shape that has an gxOpenFrameFill shape fill. You must always specify cap shapes in primitive form.
  5916. You use the gxCapRecord structure, which is described on page 3-94, when retrieving or specifying start cap and end cap information.
  5917. You can use the GXGetStyleCap function to retrieve the cap information from a style object and the GXSetStyleCap function to specify cap information for a style object.
  5918. The GXGetShapeCap and GXSetShapeCap functions provide a way to retrieve and specify cap information for the style object associated with a particular shape.
  5919. GXGetStyleCap  
  5920.  
  5921. You can use the GXGetStyleCap function to retrieve the cap information from a style object.
  5922. gxCapRecord *GXGetStyleCap(gxStyle source, gxCapRecord *cap);
  5923. source    The style object whose cap information you want to retrieve.
  5924. cap    A pointer to the source style object’s cap information.
  5925. function result    A copy of the cap record structure associated with the source style.
  5926. DESCRIPTION
  5927. The GXGetStyleCap function returns as its function result, and in the cap parameter, a cap record structure containing the cap information for the style object specified by the source parameter.
  5928. This function creates new shapes to encapsulate the start cap and end cap geometries, and places references to these shapes in the startCap and endCap fields of the returned cap record structure. You should dispose of these shapes when you no longer need them.
  5929. Since this function copies the cap information from the source style object, you may make changes to the cap record structure returned by this function without affecting the source style’s cap information. If you want to change the cap information in the source style, you must use the GXSetStyleCap function.
  5930. SPECIAL CONSIDERATIONS
  5931. If no error results, the GXGetStyleCap function creates shapes; you are responsible for disposing of these shapes when you no longer need them. See Inside Macintosh: QuickDraw GX Objects for information about disposing QuickDraw GX objects.
  5932. ERRORS, WARNINGS, AND NOTICES
  5933. Errors    
  5934. out_of_memory    
  5935. style_is_nil    
  5936. parameter_is_nil    
  5937.  
  5938. SEE ALSO
  5939. For a discussion of start and end caps, see “Caps” on page 3-23.
  5940. For examples of adding caps to a shape, see “Adding Caps to a Shape” on page 3-53 and “Adding Standard Caps to a Shape” on page 3-56.
  5941. For a discussion of the gxCapRecord structure, see “Cap Record Structure” on page 3-94.
  5942. To specify cap information for a style object, use the GXSetStyleCap function, which is described in the next section.
  5943. To retrieve cap information from a style object associated with a particular shape, use the GXGetShapeCap function, which is described on page 3-119.
  5944. To specify cap information for a style object associated with a particular shape, use the GXSetShapeCap function, which is described on page 3-120.
  5945. GXSetStyleCap  
  5946.  
  5947. You can use the GXSetStyleCap function to change the cap information of a style object.
  5948. void GXSetStyleCap(gxStyle target, gxCapRecord *cap);
  5949. target    The style object whose cap information you want to change.
  5950. cap    A pointer to the new cap information.
  5951. DESCRIPTION
  5952. The GXSetStyleCap function replaces the cap information in the style object specified by the target parameter with the cap information specified in the cap parameter. You use the gxCapRecord structure to provide cap information.
  5953. Passing nil for the cap parameter indicates that you want no caps and QuickDraw GX removes any cap information from the target style.
  5954. When you set a style’s cap property using this function, you are effectively changing the caps for all shapes that share the style.
  5955. ERRORS, WARNINGS, AND NOTICES
  5956. Errors    
  5957. out_of_memory    
  5958. style_is_nil    
  5959. parameter_out_of_range    
  5960. Notices (debugging version)    
  5961. start_cap_already_set    
  5962. end_cap_already_set    
  5963.  
  5964. SEE ALSO
  5965. For a discussion of start and end caps, see “Caps” on page 3-23.
  5966. For examples of adding caps to a shape, see “Adding Caps to a Shape” on page 3-53 and “Adding Standard Caps to a Shape” on page 3-56.
  5967. For a discussion of the gxCapRecord structure, see “Cap Record Structure” on page 3-94.
  5968. To retrieve cap information from a style object, use the GXGetStyleCap function, which is described on page 3-117.
  5969. To retrieve cap information from a style object associated with a particular shape, use the GXGetShapeCap function, which is described in the next section.
  5970. To specify cap information for a style object associated with a particular shape, use the GXSetShapeCap function, which is described on page 3-120.
  5971. GXGetShapeCap  
  5972.  
  5973. You can use the GXGetShapeCap function to retrieve cap information from the style object of a particular shape.
  5974. gxCapRecord *GXGetShapeCap(gxShape source, gxCapRecord *cap);
  5975. source    The shape whose cap information you want to retrieve.
  5976. cap    A pointer to the source shape’s cap information.
  5977. function result    A copy of the cap record structure associated with the source shape’s style object.
  5978. DESCRIPTION
  5979. The GXGetShapeCap function returns as its function result, and in the cap parameter, a gxCapRecord structure containing the cap information for the style object associated with the shape specified by the source parameter.
  5980. This function creates new shapes to encapsulate the start cap and end cap geometries, and places references to these shapes in the startCap and endCap fields of the returned gxCapRecord structure. You should dispose of these shapes when you no longer need them.
  5981. Since this function copies the cap information from the source shape’s style, you may make changes to the cap record structure returned by this function without affecting the source shape’s caps. If you want to change the cap information for the source shape, you must use the GXSetShapeCap function.
  5982. SPECIAL CONSIDERATIONS
  5983. Unless an error results, the GXGetShapeCap function creates shapes; you are responsible for disposing of these shapes when you no longer need them. See Inside Macintosh: QuickDraw GX Objects for information about disposingof QuickDraw GX objects.
  5984. ERRORS, WARNINGS, AND NOTICES
  5985. Errors    
  5986. out_of_memory    
  5987. shape_is_nil    
  5988. parameter_is_nil    
  5989.  
  5990. SEE ALSO
  5991. For a discussion of start and end caps, see “Caps” on page 3-23.
  5992. For examples of adding caps to a shape, see “Adding Caps to a Shape” on page 3-53 and “Adding Standard Caps to a Shape” on page 3-56.
  5993. For a discussion of the gxCapRecord structure, see “Cap Record Structure” on page 3-94.
  5994. To retrieve cap information from a style object, use the GXGetStyleCap function, which is described on page 3-117.
  5995. To specify cap information for a style object, use the GXSetStyleCap function, which is described on page 3-118.
  5996. To specify cap information for a style object associated with a particular shape, use the GXSetShapeCap function, which is described in the next section.
  5997. GXSetShapeCap  
  5998.  
  5999. You can use the GXSetShapeCap function to change the cap information of the style object associated with a particular shape.
  6000. void GXSetShapeCap(gxShape target, gxCapRecord *cap);
  6001. target    The shape whose cap information you want to change.
  6002. cap    A pointer to the new cap information.
  6003. DESCRIPTION
  6004. The GXSetShapeCap function replaces the cap information in the style object of the shape specified by the target parameter with the cap information specified in the cap parameter. You use the gxCapRecord structure to provide cap information.
  6005. Passing nil for the cap parameter indicates that you want no caps and QuickDraw GX removes any cap information from the target shape.
  6006. If the target shape shares its style object with other shapes, this function makes a copy of the style object, sets the target shape to reference the copy, and changes the cap property of the copy. (However, if the effect of this function would leave the cap information unchanged, this function does not create a copy of the style object; instead, it posts a notice.)
  6007. ERRORS, WARNINGS, AND NOTICES
  6008. Errors    
  6009. out_of_memory    
  6010. shape_is_nil    
  6011. parameter_out_of_range    
  6012. Notices (debugging version)    
  6013. start_cap_already_set    
  6014. end_cap_already_set    
  6015.  
  6016. SEE ALSO
  6017. For a discussion of start and end caps, see “Caps” on page 3-23.
  6018. For examples of adding caps to shapes, see “Adding Caps to a Shape” on page 3-53 and “Adding Standard Caps to a Shape” on page 3-56.
  6019. For a discussion of the gxCapRecord structure, see “Cap Record Structure” on page 3-94.
  6020. To retrieve cap information from a style object, use the GXGetStyleCap function, which is described on page 3-117.
  6021. To specify cap information for a style object, use the GXSetStyleCap function, which is described on page 3-118.
  6022. To retrieve cap information from a style object associated with a particular shape, use the GXGetShapeCap function, which is described on page 3-119.
  6023. Getting and Setting Joins
  6024.  
  6025. QuickDraw GX also allows you to specify what to draw at corners of a shape’s contours. In particular, you may specify a corner join for any rectangle, polygon, or path shape that has an open-frame shape fill or a closed-frame shape fill. You must always specify join shapes in primitive form.
  6026. You use the gxJoinRecord structure, which is described on page 3-95, when retrieving or specifying join information.
  6027. You can use the GXGetStyleJoin function to retrieve the join information from a style object and the GXSetStyleJoin function to specify join information for a style object.
  6028. The GXGetShapeJoin and GXSetShapeJoin functions provide a way to retrieve and specify join information for the style object associated with a particular shape.
  6029. GXGetStyleJoin  
  6030.  
  6031. You can use the GXGetStyleJoin function to retrieve the join information from a style object.
  6032. gxJoinRecord *GXGetStyleJoin(gxStyle source, gxJoinRecord *join);
  6033. source    The style object whose join information you want to retrieve.
  6034. join    A pointer to the source style object’s join information.
  6035. function result    A copy of the join record structure associated with the source style object.
  6036. DESCRIPTION
  6037. The GXGetStyleJoin function returns as its function result, and in the join parameter, a pointer to a join record structure containing the join information for the style object specified by the source parameter.
  6038. This function creates a new shape to encapsulate the join geometry, and places a reference to this shape in the join field of the returned join record structure. You should dispose of this shape when you no longer need it.
  6039. Since this function copies the join information from the source style, you may make changes to the join record structure returned by this function without affecting the source style’s join information. If you want to change the join information in the source style, you must use the GXSetStyleJoin function.
  6040. SPECIAL CONSIDERATIONS
  6041. Unless an error results, the GXGetStyleJoin function creates a shape; you are responsible for disposing of this shape when you no longer need it. See Inside Macintosh: QuickDraw GX Objects for information about disposing of QuickDraw GX objects.
  6042. ERRORS, WARNINGS, AND NOTICES
  6043. Errors    
  6044. out_of_memory    
  6045. style_is_nil    
  6046. parameter_is_nil    
  6047.  
  6048. SEE ALSO
  6049. For a discussion of joins, see “Joins” on page 3-25.
  6050. For examples of adding joins to shapes, see “Adding Joins to a Shape” on page 3-58 and “Adding Standard Joins to a Shape” on page 3-61.
  6051. For a discussion of the gxJoinRecord structure, see “Join Record Structure” on page 3-95.
  6052. To specify join information for a style object, use the GXSetStyleJoin function, which is described in the next section.
  6053. To retrieve join information from a style object associated with a particular shape, use the GXGetShapeJoin function, which is described on page 3-124.
  6054. To specify join information for a style object associated with a particular shape, use the GXSetShapeJoin function, which is described on page 3-125.
  6055. GXSetStyleJoin  
  6056.  
  6057. You can use the GXSetStyleJoin function to change a style object’s join information.
  6058. void GXSetStyleJoin(gxStyle target, const gxJoinRecord *join);
  6059. target    The style object whose join information you want to change.
  6060. join    A pointer to the new join information.
  6061. DESCRIPTION
  6062. The GXSetStyleJoin function replaces the join information in the style object specified by the target parameter with the join information specified in the join parameter. You use the gxJoinRecord structure to provide join information.
  6063. Passing nil for the join parameter indicates that you want no join shape and QuickDraw GX removes any join information from the target style.
  6064. When you set a style’s join property using this function, you are effectively changing the joins for all shapes that share the style.
  6065. ERRORS, WARNINGS, AND NOTICES
  6066. Errors    
  6067. out_of_memory    
  6068. style_is_nil    
  6069. parameter_out_of_range    
  6070. Notices (debugging version)    
  6071. join_type_already_set    
  6072.  
  6073. SEE ALSO
  6074. For a discussion of joins, see “Joins” on page 3-25.
  6075. For examples of adding joins to shapes, see “Adding Joins to a Shape” on page 3-58 and “Adding Standard Joins to a Shape” on page 3-61.
  6076. For a discussion of the gxJoinRecord structure, see “Join Record Structure” on page 3-95.
  6077. To retrieve join information from a style object, use the GXGetStyleJoin function, which is described on page 3-122.
  6078. To retrieve join information from a style object associated with a particular shape, use the GXGetShapeJoin function, which is described in the next section.
  6079. To specify join information for a style object associated with a particular shape, use the GXSetShapeJoin function, which is described on page 3-125.
  6080. GXGetShapeJoin  
  6081.  
  6082. You can use the GXGetShapeJoin function to retrieve the join information from the style object of a shape.
  6083. gxJoinRecord *GXGetShapeJoin(gxShape source, gxJoinRecord *join);
  6084. source    The shape whose join information you want to retrieve.
  6085. join    A pointer to the source shape’s join information.
  6086. function result    A copy of the join record structure associated with the source shape’s style object.
  6087. DESCRIPTION
  6088. The GXGetShapeJoin function returns as its function result, and in the join parameter, a pointer to a join record structure containing the join information for the style object of the shape specified by the source parameter.
  6089. This function creates a new shape to encapsulate the join geometry, and places a reference to this shape in the join field of the returned join record structure. You should dispose of this shape when you no longer need it.
  6090. Since this function copies the join information from the source shape’s style, you may make changes to the join record returned by this function without affecting the source shape’s joins. If you want to change the join information for the source shape, you must use the GXSetShapeJoin function.
  6091. SPECIAL CONSIDERATIONS
  6092. Unless an error results, the GXGetShapeJoin function creates a shape; you are responsible for disposing of this shape when you no longer need it. See Inside Macintosh: QuickDraw GX Objects for information about disposing of QuickDraw GX objects.
  6093. ERRORS, WARNINGS, AND NOTICES
  6094. Errors    
  6095. out_of_memory    
  6096. shape_is_nil    
  6097. parameter_is_nil    
  6098.  
  6099. SEE ALSO
  6100. For a discussion of joins, see “Joins” on page 3-25.
  6101. For examples of adding joins to shapes, see “Adding Joins to a Shape” on page 3-58 and “Adding Standard Joins to a Shape” on page 3-61.
  6102. For a discussion of the gxJoinRecord structure, see “Join Record Structure” on page 3-95.
  6103. To retrieve join information from a style object, use the GXGetStyleJoin function, which is described on page 3-122.
  6104. To specify join information for a style object, use the GXSetStyleJoin function, which is described on page 3-123.
  6105. To specify join information for a style object associated with a particular shape, use the GXSetShapeJoin function, which is described in the next section.
  6106. GXSetShapeJoin  
  6107.  
  6108. You can use the GXSetShapeJoin function to change the join information for the style object of a particular shape.
  6109. void GXSetShapeJoin(gxShape target, const gxJoinRecord *join);
  6110. target    The shape whose join information you want to change.
  6111. join    A pointer to new join information.
  6112. DESCRIPTION
  6113. The GXSetShapeJoin function replaces the join information in the style object of the shape specified by the target parameter with the join information provided in the join parameter. You use the gxJoinRecord structure to provide join information.
  6114. Passing nil for the join parameter indicates that you want no joins and QuickDraw GX removes any join information from the target shape.
  6115. If the target shape shares its style object with other shapes, this function makes a copy of the style object, sets the target shape to reference the copy, and changes the join property of the copy. (However, if the effect of this function would leave the join information unchanged, this function does not create a copy of the style object; instead, it posts a notice.)
  6116. ERRORS, WARNINGS, AND NOTICES
  6117. Errors    
  6118. out_of_memory    
  6119. shape_is_nil    
  6120. parameter_out_of_range    
  6121. Notices (debugging version)    
  6122. join_type_already_set    
  6123.  
  6124. SEE ALSO
  6125. For a discussion of joins, see “Joins” on page 3-25.
  6126. For examples of adding joins to shapes, see “Adding Joins to a Shape” on page 3-58 and “Adding Standard Joins to a Shape” on page 3-61.
  6127. For a discussion of the gxJoinRecord structure, see “Join Record Structure” on page 3-95.
  6128. To retrieve join information from a style object, use the GXGetStyleJoin function, which is described on page 3-122.
  6129. To specify join information for a style object, use the GXSetStyleJoin function, which is described on page 3-123.
  6130. To retrieve join information from a style object associated with a particular shape, use the GXGetShapeJoin function, which is described on page 3-124.
  6131. Getting and Setting Dashes
  6132.  
  6133. QuickDraw GX allows you to specify how contours of a shape should be dashed when drawn. In particular, you may specify a dash shape for any line, curve, rectangle, polygon, or path shape that has an open-frame shape fill or a closed-frame shape fill. You must always specify dash shapes in primitive form.
  6134. You use the gxDashRecord structure, which is described on page 3-97, when retrieving or specifying dash information.
  6135. You can use the GXGetStyleDash function to retrieve the dash information from a style object and the GXSetStyleDash function to specify dash information for a style object.
  6136. The GXGetShapeDash and GXSetShapeDash functions provide a way to retrieve and specify dash information for the style object associated with a particular shape.
  6137. GXGetStyleDash  
  6138.  
  6139. You can use the GXGetStyleDash function to retrieve the dash information from a style object.
  6140. gxDashRecord *GXGetStyleDash(gxStyle source, gxDashRecord *dash);
  6141. source    The style object whose dash information you want to retrieve.
  6142. dash    A pointer to source style object’s dash information.
  6143. function result    A copy of the dash record structure associated with the source style object.
  6144. DESCRIPTION
  6145. The GXGetStyleDash function returns as its function result, and in the dash parameter, a pointer to a gxDashRecord structure containing the dash information for the style object specified by the source parameter.
  6146. This function creates a new shape to encapsulate the dash geometry, and places a reference to this shape in the dash field of the returned gxDashRecord structure. You should dispose of this shape when you no longer need it.
  6147. Since this function copies the dash information from the source style, you may make changes to the dash record structure returned by this function without affecting the source style’s dash information. If you want to change the dash information in the source style, you must use the GXSetStyleDash function.
  6148. SPECIAL CONSIDERATIONS
  6149. Unless an error results, the GXGetStyleDash function creates a shape; you are responsible for disposing of this shape when you no longer need it. See Inside Macintosh: QuickDraw GX Objects for information about disposing of QuickDraw GX objects.
  6150. ERRORS, WARNINGS, AND NOTICES
  6151. Errors    
  6152. out_of_memory    
  6153. style_is_nil    
  6154. parameter_is_nil    
  6155.  
  6156. SEE ALSO
  6157. For a discussion of dashes, see “Dashes” on page 3-27.
  6158. For examples of adding dashes to shapes, see page 3-63 through page 3-81.
  6159. For a discussion of the gxDashRecord structure, see “Dash Record Structure” on page 3-97.
  6160. To specify dash information for a style object, use the GXSetStyleDash function, which is described in the next section.
  6161. To retrieve dash information from a style object associated with a particular shape, use the GXGetShapeDash function, which is described on page 3-129.
  6162. To specify dash information for a style object associated with a particular shape, use the GXSetShapeDash function, which is described on page 3-130.
  6163. To determine where dashing occurs for a particular shape, use the GXGetShapeDashPositions function, which is described on page 3-131.
  6164. GXSetStyleDash  
  6165.  
  6166. You can use the GXSetStyleDash function to change a style object’s dash information.
  6167. void GXSetStyleDash(gxStyle target, const gxDashRecord *dash);
  6168. target    The style object whose dash information you want to change.
  6169. dash    A pointer to the new dash information.
  6170. DESCRIPTION
  6171. The GXSetStyleDash function replaces the dash information in the style object specified by the target parameter with the dash information provided by the dash parameter. You use the gxDashRecord structure to provide dash information.
  6172. Passing nil for the dash parameter indicates that you want no dashing to occur and QuickDraw GX removes any dash information from the target style.
  6173. When you set a style’s dash property using this function, you are effectively changing the dashes for all shapes that share the style.
  6174. ERRORS, WARNINGS, AND NOTICES
  6175. Errors    
  6176. out_of_memory    
  6177. style_is_nil    
  6178. parameter_out_of_range    
  6179. Notices (debugging version)    
  6180. dash_already_set    
  6181.  
  6182. SEE ALSO
  6183. For a discussion of dashes, see “Dashes” on page 3-27.
  6184. For examples of adding dashes to shapes, see page 3-63 through page 3-81.
  6185. For a discussion of the gxDashRecord structure, see “Dash Record Structure” on page 3-97.
  6186. To retrieve dash information from a style object, use the GXGetStyleDash function, which is described on page 3-126.
  6187. To retrieve dash information from a style object associated with a particular shape, use the GXGetShapeDash function, which is described in the next section.
  6188. To specify dash information for a style object associated with a particular shape, use the GXSetShapeDash function, which is described on page 3-130.
  6189. To determine where dashing occurs for a particular shape, use the GXGetShapeDashPositions function, which is described on page 3-131.
  6190. GXGetShapeDash  
  6191.  
  6192. You can use the GXGetShapeDash function to retrieve the dash information from the style object associated with a particular shape.
  6193. gxDashRecord *GXGetShapeDash(gxShape source, gxDashRecord *dash);
  6194. source    The shape whose dash information you want to retrieve.
  6195. dash    A pointer to the source shape’s dash information.
  6196. function result    A copy of the dash record structure associated with the source shape’s style object.
  6197. DESCRIPTION
  6198. The GXGetShapeDash function returns as its function result and in the dash parameter, a pointer to a gxDashRecord structure containing the dash information for the style object of the shape specified by the source parameter.
  6199. This function creates a new shape to encapsulate the dash geometry, and places a reference to this shape in the dash field of the returned gxDashRecord structure. You should dispose of this shape when you no longer need it.
  6200. Since this function copies the dash information from the source shape’s style, you may make changes to the dash record structure returned by this function without affecting the source shape’s dashes. If you want to change the dash information for the source shape, you must use the GXSetShapeDash function.
  6201. SPECIAL CONSIDERATIONS
  6202. Unless an error results, the GXGetShapeDash function creates a shape; you are responsible for disposing of this shape when you no longer need it. See Inside Macintosh: QuickDraw GX Objects for information about disposing of objects.
  6203. ERRORS, WARNINGS, AND NOTICES
  6204. Errors    
  6205. out_of_memory    
  6206. shape_is_nil    
  6207. parameter_is_nil    
  6208.  
  6209. SEE ALSO
  6210. For a discussion of dashes, see “Dashes” on page 3-27.
  6211. For examples of adding dashes to shapes, see page 3-63 through page 3-81.
  6212. For a discussion of the gxDashRecord structure, see “Dash Record Structure” on page 3-97.
  6213. To retrieve dash information from a style object, use the GXGetStyleDash function, which is described on page 3-126.
  6214. To specify dash information for a style object, use the GXSetStyleDash function, which is described on page 3-128.
  6215. To specify dash information for a style object associated with a particular shape, use the GXSetShapeDash function, which is described in the next section.
  6216. To determine where dashing occurs for a particular shape, use the GXGetShapeDashPositions function, which is described on page 3-131.
  6217. GXSetShapeDash  
  6218.  
  6219. You can use the GXSetShapeDash function to change the dash information for a style object associated with a particular shape.
  6220. void GXSetShapeDash(gxShape target, const gxDashRecord *dash);
  6221. target    The shape whose dash information you want to change.
  6222. dash    A pointer to the new dash information.
  6223. DESCRIPTION
  6224. The GXSetShapeDash function replaces the dash information in the style object of the shape specified by the target parameter with the dash information provided by the dash parameter. You use the gxDashRecord structure to provide dash information.
  6225. Passing nil for the dash parameter indicates that you want no dashing to occur and QuickDraw GX removes any dash information from the target shape.
  6226. If the target shape shares its style object with other shapes, this function makes a copy of the style object, sets the target shape to reference the copy, and changes the dash property of the copy. (However, if the effect of this function would leave the dash information unchanged, this function does not create a copy of the style object; instead, it returns a notice.)
  6227. ERRORS, WARNINGS, AND NOTICES
  6228. Errors    
  6229. out_of_memory    
  6230. shape_is_nil    
  6231. parameter_out_of_range    
  6232. Warnings    
  6233. graphic_type_cannot_be_dashed    
  6234. Notices (debugging version)    
  6235. dash_already_set    
  6236.  
  6237. SEE ALSO
  6238. For a discussion of dashes, see “Dashes” on page 3-27.
  6239. For examples of adding dashes to shapes, see page 3-63 through page 3-81.
  6240. For a discussion of the gxDashRecord structure, see “Dash Record Structure” on page 3-97.
  6241. To retrieve dash information from a style object, use the GXGetStyleDash function, which is described on page 3-126.
  6242. To specify dash information for a style object, use the GXSetStyleDash function, which is described on page 3-128.
  6243. To retrieve dash information from a style object associated with a particular shape, use the GXGetShapeDash function, which is described on page 3-129.
  6244. To determine where dashing occurs for a particular shape, use the GXGetShapeDashPositions function, which is described in the next section.
  6245. GXGetShapeDashPositions  
  6246.  
  6247. You can use the GXGetShapeDashPositions function to determine the precise locations where QuickDraw GX draws a particular shape’s dashes.
  6248. long GXGetShapeDashPositions(gxShape source, 
  6249.                                       gxMapping dashMappings[]);
  6250. source    The shape whose dash positions you want to find.
  6251. dashMappings
  6252. An array of dash positions.
  6253. function result    The number of dash positions returned in the dashMappings parameter.
  6254. DESCRIPTION
  6255. The GXGetShapeDashPositions function returns in the dashMappings parameter mappings that indicate the locations and rotations of the dashes as drawn along the contours of the source shape.
  6256. The function result is the number of dash positions returned—the number of dash shapes drawn along the contours of the source shape.
  6257. If you pass nil for the dashMappings parameter, the GXGetShapeDashPositions function still returns as the function result the number of dashes but it does return the positions of the dashes.
  6258. This function returns 0 if the source shape is not dashed.
  6259. ERRORS, WARNINGS, AND NOTICES
  6260. Errors    
  6261. out_of_memory    
  6262. shape_is_nil    
  6263. Warnings    
  6264. graphic_type_cannot_be_dashed    
  6265.  
  6266. SEE ALSO
  6267. For a discussion of dashes, see “Dashes” on page 3-27.
  6268. For an example of using this function, see “Determining Dash Positions” on page 3-77.
  6269. For a discussion of the gxDashRecord structure, see “Dash Record Structure” on page 3-97.
  6270. To retrieve dash information from a style object, use the GXGetStyleDash function, which is described on page 3-126.
  6271. To specify dash information for a style object, use the GXSetStyleDash function, which is described on page 3-128.
  6272. To retrieve dash information from a style object associated with a particular shape, use the GXGetShapeDash function, which is described on page 3-129.
  6273. To specify dash information for a style object associated with a particular shape, use the GXSetShapeDash function, which is described on page 3-130.
  6274. Getting and Setting Patterns
  6275.  
  6276. QuickDraw GX allows you to specify a pattern to fill a shape when drawn. In particular, you may specify a pattern shape for any line, curve, rectangle, polygon, or path shape that has any framed shape fill or any solid fill. You must always specify pattern shapes in their primitive form.
  6277. You use the gxPatternRecord structure, which is described on page 3-99, when retrieving or specifying pattern information.
  6278. You can use the GXGetStylePattern function to retrieve the pattern information from a style object and the GXSetStylePattern function to specify pattern information for a style object.
  6279. The GXGetShapePattern and GXSetShapePattern functions provide a way to retrieve and specify pattern information for the style object associated with a particular shape.
  6280. GXGetStylePattern  
  6281.  
  6282. You can use the GXGetStylePattern function to retrieve the pattern information from a style object.
  6283. gxPatternRecord *GXGetStylePattern(gxStyle source, 
  6284.                                              gxPatternRecord *pattern);
  6285. source    The style object whose pattern information you want to retrieve.
  6286. pattern    A pointer the source style object’s pattern information.
  6287. function result    A copy of the pattern record structure associated with the source style object.
  6288. DESCRIPTION
  6289. The GXGetStylePattern function returns as its function result, and in the pattern parameter, a pointer to a pattern record structure containing the pattern information for the style object specified by the source parameter.
  6290. This function creates a new shape to encapsulate the pattern geometry, and places a reference to this shape in the pattern field of the returned gxPatternRecord structure. You should dispose of this shape when you no longer need it.
  6291. Since this function copies the pattern information from the source style, you may make changes to the pattern record structure returned by this function without affecting the source style’s pattern information. If you want to change the pattern information in the source style, you must use the GXSetStylePattern function.
  6292. SPECIAL CONSIDERATIONS
  6293. Unless an error results the GXGetStylePattern function creates a shape; you are responsible for disposing of this shape when you no longer need it. See Inside Macintosh: QuickDraw GX Objects for information about disposing of QuickDraw GX objects.
  6294. ERRORS, WARNINGS, AND NOTICES
  6295. Errors    
  6296. out_of_memory    
  6297. style_is_nil    
  6298. parameter_is_nil    
  6299.  
  6300. SEE ALSO
  6301. For a discussion of patterns, see “Patterns” on page 3-31.
  6302. For examples of adding patterns to shapes, see page 3-81 through page 3-86.
  6303. For a discussion of the gxPatternRecord structure, see “Pattern Record Structure” on page 3-99.
  6304. To specify pattern information for a style object, use the GXSetStylePattern function, which is described in the next section.
  6305. To retrieve pattern information from a style object associated with a particular shape, use the GXGetShapePattern function, which is described on page 3-135.
  6306. To specify pattern information for a style object associated with a particular shape, use the GXSetShapePattern function, which is described on page 3-137.
  6307. To determine where pattern shapes are drawn for a particular shape, use the GXGetShapePatternPositions function, which is described on page 3-138.
  6308. GXSetStylePattern  
  6309.  
  6310. You can use the GXSetStylePattern function to change a style object’s pattern information.
  6311. void GXSetStylePattern(gxStyle target, 
  6312.                               const gxPatternRecord *pattern);
  6313. target    The style object whose pattern information you want to change.
  6314. pattern    A pointer to the new pattern information.
  6315. DESCRIPTION
  6316. The GXSetStylePattern function replaces the pattern information in the style object specified by the target parameter with the pattern information provided by the pattern parameter. You use the gxPatternRecord structure to provide pattern information.
  6317. Passing nil for the pattern parameter indicates that you want no pattern and QuickDraw GX removes any pattern information from the target style.
  6318. When you set a style’s pattern property using this function, you are effectively changing the pattern for all shapes that share the style.
  6319. ERRORS, WARNINGS, AND NOTICES
  6320. Errors    
  6321. out_of_memory    
  6322. style_is_nil    
  6323. parameter_out_of_range    
  6324. pattern_lattice_out_of_range    
  6325. Notices (debugging version)    
  6326. pattern_already_set    
  6327.  
  6328. SEE ALSO
  6329. For a discussion of patterns, see “Patterns” on page 3-31.
  6330. For examples of adding patterns to shapes, see page 3-81 through page 3-86.
  6331. For a discussion of the gxPatternRecord structure, see “Pattern Record Structure” on page 3-99.
  6332. To retrieve pattern information from a style object, use the GXGetStylePattern function, which is described on page 3-133.
  6333. To retrieve pattern information from a style object associated with a particular shape, use the GXGetShapePattern function, which is described in the next section.
  6334. To specify pattern information for a style object associated with a particular shape, use the GXSetShapePattern function, which is described on page 3-137.
  6335. To determine where pattern shapes are drawn for a particular shape, use the GXGetShapePatternPositions function, which is described on page 3-138.
  6336. GXGetShapePattern  
  6337.  
  6338. You can use the GXGetShapePattern function to retrieve the pattern information from the style object associated with a particular shape.
  6339. gxPatternRecord *GXGetShapePattern(gxShape source, 
  6340.                                              gxPatternRecord *pattern);
  6341. source    The shape whose pattern information you want to retrieve.
  6342. pattern    A pointer to the source shape’s pattern information.
  6343. function result    A copy of the pattern record structure associated with the source shape’s style object.
  6344. DESCRIPTION
  6345. The GXGetShapePattern function returns as its function result and in the pattern parameter a pointer to a gxPatternRecord structure containing the pattern information for the style object of the shape specified by the source parameter.
  6346. This function creates a new shape to encapsulate the pattern geometry, and places a reference to this shape in the pattern field of the returned gxPatternRecord structure. You should dispose of this shape when you no longer need it.
  6347. Since this function copies the pattern information from the source shape’s style, you may make changes to the pattern record structure returned by this function without affecting the source shape’s pattern. If you want to change the pattern information for the source shape, you must use the GXSetShapePattern function.
  6348. SPECIAL CONSIDERATIONS
  6349. The GXGetShapePattern function may create a shape; you are responsible for disposing of this shape when you no longer need it. See Inside Macintosh: QuickDraw GX Objects for information about creating and disposing of objects.
  6350. ERRORS, WARNINGS, AND NOTICES
  6351. Errors    
  6352. out_of_memory    
  6353. shape_is_nil    
  6354. parameter_is_nil    
  6355.  
  6356. SEE ALSO
  6357. For a discussion of patterns, see “Patterns” on page 3-31.
  6358. For examples of adding patterns to shapes, see page 3-81 through page 3-86.
  6359. For a discussion of the gxPatternRecord structure, see “Pattern Record Structure” on page 3-99.
  6360. To retrieve pattern information from a style object, use the GXGetStylePattern function, which is described on page 3-133.
  6361. To specify pattern information for a style object, use the GXSetStylePattern function, which is described on page 3-134.
  6362. To specify pattern information for a style object associated with a particular shape, use the GXSetShapePattern function, which is described in the next section.
  6363. To determine where pattern shapes are drawn for a particular shape, use the GXGetShapePatternPositions function, which is described on page 3-138.
  6364. GXSetShapePattern  
  6365.  
  6366. You can use the GXSetShapePattern function to change the pattern information for a style object associated with a particular shape.
  6367. void GXSetShapePattern(gxShape target, 
  6368.                               const gxPatternRecord *pattern);
  6369. target    The shape whose pattern information you want to change.
  6370. pattern    A pointer to the new pattern information.
  6371. DESCRIPTION
  6372. The GXSetShapePattern function replaces the pattern information in the style object of the shape specified by the target parameter with the pattern information provided by the pattern parameter. You use the gxPatternRecord structure to provide pattern information.
  6373. Passing nil for the pattern parameter indicates that you want no pattern and QuickDraw GX removes any pattern information from the target shape.
  6374. If the target shape shares its style object with other shapes, this function makes a copy of the style object, sets the target shape to reference the copy, and changes the pattern property of the copy. (However, if the effect of this function would leave the pattern information unchanged, this function does not create a copy of the style object; instead, it returns a notice).
  6375. ERRORS, WARNINGS, AND NOTICES
  6376. Errors    
  6377. out_of_memory    
  6378. shape_is_nil    
  6379. parameter_out_of_range    
  6380. pattern_lattice_out_of_range    
  6381. Notices    
  6382. pattern_already_set    
  6383.  
  6384. SEE ALSO
  6385. For a discussion of patterns, see “Patterns” on page 3-31.
  6386. For examples of adding patterns to shapes, see page 3-81 through page 3-86.
  6387. For a discussion of the gxPatternRecord structure, see “Pattern Record Structure” on page 3-99.
  6388. To retrieve pattern information from a style object, use the GXGetStylePattern function, which is described on page 3-133.
  6389. To specify pattern information for a style object, use the GXSetStylePattern function, which is described on page 3-134.
  6390. To retrieve pattern information from a style object associated with a particular shape, use the GXGetShapePattern function, which is described on page 3-135.
  6391. To determine where pattern shapes are drawn for a particular shape, use the GXGetShapePatternPositions function, which is described in the next section.
  6392. GXGetShapePatternPositions  
  6393.  
  6394. You can use the GXGetShapePatternPositions function to determine the precise locations where QuickDraw GX draws the shapes that pattern another shape.
  6395. long GXGetShapePatternPositions(gxShape source, 
  6396.                                           gxPoint positions[]);
  6397. source    The shape whose pattern positions you want to find.
  6398. positions    An array of pattern positions.
  6399. function result    The number of pattern positions returned in the positions parameter.
  6400. DESCRIPTION
  6401. The GXGetShapePatternPositions function returns in the positions parameter the locations of the pattern shapes as drawn for the source shape.
  6402. The function result is the number of pattern positions returned—the number of pattern shapes drawn for the source shape.
  6403. If you pass nil for the positions parameter, the GXGetShapePatternPositions function still returns as the function result the number of pattern shapes but it does return the positions of the pattern shapes.
  6404. This function returns 0 if the source shape has no pattern.
  6405. ERRORS, WARNINGS, AND NOTICES
  6406. Errors    
  6407. out_of_memory    
  6408. shape_is_nil    
  6409.  
  6410. SEE ALSO
  6411. For a discussion of patterns, see “Patterns” on page 3-31.
  6412. For an example using this function, see “Determining Pattern Positions” on page 3-83.
  6413. For a discussion of the gxPatternRecord structure, see “Pattern Record Structure” on page 3-99.
  6414. To retrieve pattern information from a style object, use the GXGetStylePattern function, which is described on page 3-133.
  6415. To specify pattern information for a style object, use the GXSetStylePattern function, which is described on page 3-134.
  6416. To retrieve pattern information from a style object associated with a particular shape, use the GXGetShapePattern function, which is described on page 3-135.
  6417. To specify pattern information for a style object associated with a particular shape, use the GXSetShapePattern function, which is described on page 3-137.
  6418.  
  6419.  
  6420. Summary of Geometric Styles
  6421.  
  6422. Constants and Data Types
  6423.  
  6424. Style Object
  6425. typedef struct gxPrivateStyleRecord *gxStyle;
  6426. Style Attributes
  6427. enum gxStyleAttributes {
  6428.     gxCenterFrameStyle                            = 0,                /* center the pen on contour */
  6429.     gxSourceGridStyle                            = 0x0001,                /* constrain to source grid */
  6430.     gxDeviceGridStyle                            = 0x0002,                /* constrain to device grid */
  6431.     gxInsideFrameStyle                            = 0x0004,                /* place pen inside contour */
  6432.     gxOutsideFrameStyle                            = 0x0008,                /* place pen outside contour */
  6433.     gxAutoInsetStyle                            = 0x0010                /* don’t assume right is in */
  6434. };
  6435. typedef long gxStyleAttribute;
  6436. Cap Record Structure
  6437. struct gxCapRecord {
  6438.     gxCapAttribute                    attributes;                /* modifies behavior of caps */
  6439.     gxShape                    startCap;                /* shape to use at start of contours */
  6440.     gxShape                    endCap;                /* shape to use at end of contours */
  6441. };
  6442. Cap Attributes
  6443. enum gxCapAttributes{
  6444.     gxLevelStartCap                    = 0x0001;                /* suppress start cap rotation */
  6445.     gxLevelEndCap                    = 0x0002;                /* suppress end cap rotation */
  6446. };
  6447. typedef long gxCapAttribute;
  6448. Join Record Structure
  6449. struct gxJoinRecord {
  6450.     gxJoinAttribute                     attributes;                 /* modifies behavior of joins */
  6451.     gxShape                     join;                 /* sape to use at corners */
  6452.     fixed                     miter;                 /* size limit for sharp joins */
  6453. };
  6454. Join Attributes
  6455. enum gxJoinAttributes {
  6456.     gxSharpJoin                = 0x0000,                /* use default sharp joins */
  6457.     gxCurveJoin                = 0x0001,                /* use default curved joins */
  6458.     gxLevelJoin                = 0x0002                /* suppress join gxShape rotation */
  6459. };
  6460. typedef long gxJoinAttribute;
  6461. Dash Record Structure
  6462. struct gxDashRecord {
  6463.     gxDashAttribute                     attributes; /* modifier flags */
  6464.     gxShape                       dash;                 /* shape used for dashing */
  6465.     fixed                       advance;                 /* distance between dashes */
  6466.     fract                       phase;                 /* start offset into the gxPath */
  6467.     fixed                       scale;                 /* height of dash (mapped to pen) */
  6468. };
  6469. Dash Attributes
  6470. typedef enum gxDashAttributes {
  6471.     gxBendDash                        = 0x0001;                  /* distorts shape in 1 dimension */
  6472.     gxBreakDash                        = 0x0002;                    /* places dash contours separately */
  6473.     gxClipDash                        = 0x0004;                    /* clips dashes to pen width */
  6474.     gxLevelDash                        = 0x0008;                  /* suppresses dash rotation */
  6475.     gxAutoAdvanceDash = 0x0010;                                            /* automatically adjusts advances */
  6476. };
  6477. typedef long gxDashAttribute;
  6478. Pattern Record Structure
  6479. struct gxPatternRecord {
  6480.     gxPatternAttribute                        attributes;                /* modifies behavior of pattern */
  6481.     gxShape                        pattern;                /* shape to use as pattern */
  6482.     gxPoint                        u;                /* vector for pattern grid */
  6483.     gxPoint                        v;                /* vector for pattern grid */
  6484. };
  6485. Pattern Attributes
  6486. enum gxPatternAttributes {
  6487.     gxPortAlignPattern = 0x0001, /* align pattern with device */
  6488.     gxPortMapPattern                         = 0x0002              /* suppress gxMapping of pattern */
  6489. };
  6490. typedef long gxPatternAttribute;
  6491. Functions for Manipulating Geometric Style Properties
  6492.  
  6493. Getting and Setting Style Attributes
  6494. gxStyleAttribute GXGetStyleAttributes 
  6495. (gxStyle source);
  6496. void GXSetStyleAttributes    (gxStyle target, gxStyleAttribute attributes);
  6497. gxStyleAttribute GXGetShapeStyleAttributes 
  6498. (gxShape source);
  6499. void GXSetShapeStyleAttributes
  6500. (gxShape target, gxStyleAttribute attributes);
  6501. Getting and Setting Curve Error
  6502. fixed GXGetStyleCurveError    (gxStyle source);
  6503. void GXSetStyleCurveError    (gxStyle target, fixed error);
  6504. fixed GXGetShapeCurveError    (gxShape source);
  6505. void GXSetShapeCurveError    (gxShape target, fixed error);
  6506. Getting and Setting the Pen Width
  6507. fixed GXGetStylePen    (gxStyle source);
  6508. void GXSetStylePen    (gxStyle target, fixed pen);
  6509. fixed GXGetShapePen    (gxShape source);
  6510. void GXSetShapePen    (gxShape target, fixed pen);
  6511. Getting and Setting Caps
  6512. gxCapRecord *GXGetStyleCap    (gxStyle source, gxCapRecord *cap);
  6513. void GXSetStyleCap    (gxStyle target, gxCapRecord *cap);
  6514. gxCapRecord *GXGetShapeCap    (gxShape source, gxCapRecord *cap);
  6515. void GXSetShapeCap    (gxShape target, gxCapRecord *cap);
  6516. Getting and Setting Joins
  6517. gxJoinRecord *GXGetStyleJoin
  6518. (gxStyle source, gxJoinRecord *join);
  6519. void GXSetStyleJoin    (gxStyle target, const gxJoinRecord *join);
  6520. gxJoinRecord *GXGetShapeJoin
  6521. (gxShape source, gxJoinRecord *join);
  6522. void GXSetShapeJoin    (gxShape target, const gxJoinRecord *join);
  6523. Getting and Setting Dashes
  6524. *GXGetStyleDash    (gxStyle source, gxDashRecord *dash);
  6525. void GXSetStyleDash    (gxStyle target, const gxDashRecord *dash);
  6526. gxDashRecord *GXGetShapeDash
  6527. (gxShape source, gxDashRecord *dash);
  6528. void GXSetShapeDash    (gxShape target, const gxDashRecord *dash);
  6529. long GXGetShapeDashPositions
  6530. (gxShape source, gxMapping dashMappings[]);
  6531. Getting and Setting Patterns
  6532. gxPatternRecord *GXGetStylePattern 
  6533. (gxStyle source, gxPatternRecord *pattern);
  6534. void GXSetStylePattern    (gxStyle target, const gxPatternRecord *pattern);
  6535. gxPatternRecord *GXGetShapePattern 
  6536. (gxShape source,
  6537. gxPatternRecord *pattern);
  6538. void GXSetShapePattern    (gxShape target, const gxPatternRecord *pattern);
  6539. long GXGetShapePatternPositions 
  6540. (gxShape source, gxPoint positions[]);
  6541. Listing 4-0
  6542. Table 4-0
  6543. Geometric Operations
  6544. Contents
  6545. About Geometric Operations4-3
  6546. Contours and Contour Direction4-4
  6547. Reducing and Simplifying Shape Geometries4-8
  6548. The Primitive Form of Shape Geometries4-10
  6549. Geometric Information4-14
  6550. Intersection and Inclusion4-16
  6551. Geometric Arithmetic4-19
  6552. Using Geometric Operations4-21
  6553. Determining and Reversing Contour Direction4-21
  6554. Breaking Shape Contours4-25
  6555. Eliminating Unnecessary Geometric Points4-27
  6556. Simplifying Shapes4-29
  6557. Converting a Shape to Primitive Form4-34
  6558. Finding Geometric Information About a Shape4-36
  6559. Setting a Shape’s Bounding Rectangle4-42
  6560. Insetting Shapes4-45
  6561. Determining Whether Two Shapes Touch4-47
  6562. Determining Whether One Shape Contains Another4-51
  6563. Performing Geometric Arithmetic With Shapes4-53
  6564. Geometric Operations Reference4-60
  6565. Constants and Data Types4-60
  6566. Contour Directions4-60
  6567. Functions4-60
  6568. Determining and Reversing Contour Direction4-61
  6569. GXGetShapeDirection 4-61
  6570. GXReverseShape 4-63
  6571. Breaking Shape Contours4-64
  6572. GXBreakShape 4-64
  6573. Reducing and Simplifying Shapes4-65
  6574. GXReduceShape 4-66
  6575. GXSimplifyShape 4-67
  6576. Incorporating Style Information Into Shape Geometries4-69
  6577. GXPrimitiveShape 4-69
  6578. Finding Geometric Information About Shapes4-71
  6579. GXGetShapeLength  4-71
  6580. GXShapeLengthToPoint 4-72
  6581. GXGetShapeCenter 4-73
  6582. GXGetShapeArea 4-74
  6583. Getting and Setting Shape Bounds4-76
  6584. GXGetShapeBounds 4-76
  6585. GXSetShapeBounds 4-77
  6586. Insetting Shapes4-79
  6587. GXInsetShape 4-79
  6588. Determining Whether Two Areas Intersect4-80
  6589. GXTouchesRectanglePoint 4-80
  6590. GXTouchesBoundsShape 4-81
  6591. GXTouchesShape 4-82
  6592. Determining Whether One Shape Contains Another4-83
  6593. GXContainsRectangle 4-84
  6594. GXContainsBoundsShape 4-85
  6595. GXContainsShape 4-86
  6596. Performing Geometric Arithmetic with Shapes4-87
  6597. GXIntersectRectangle 4-87
  6598. GXUnionRectangle 4-88
  6599. GXIntersectShape 4-89
  6600. GXUnionShape 4-91
  6601. GXDifferenceShape 4-92
  6602. GXReverseDifferenceShape 4-94
  6603. GXExcludeShape 4-95
  6604. GXInvertShape 4-96
  6605. Summary of Geometric Operations4-98
  6606. Constants and Data Types4-98
  6607. Functions4-98
  6608. Geometric Operations
  6609. This chapter describes the functions that allow you to perform geometric operations on geometric shapes. Some of the geometric operations described in this chapter work on other types of shapes as well. You should read this chapter if you create any kind of geometric shapes and want to know more about the functions available for manipulating them.
  6610. Before reading this chapter, you should be familiar with the QuickDraw GX object architecture as described in Inside Macintosh: QuickDraw GX Objects. You should also be familiar with the information in the chapters “Geometric Shapes” and “Geometric Styles” in this book.
  6611. For more information about geometric manipulation of shapes, you might want to read the chapter “Transform Objects” in Inside Macintosh: QuickDraw GX Objects and the chapter “QuickDraw GX Mathematics” of Inside Macintosh: QuickDraw GX Environment and Utilities.
  6612. This chapter introduces the basic categories of geometric operations and shows how to use these operations to:
  6613. n    determine and reverse contour direction 
  6614. n    simplify the geometric description of a shape
  6615. n    find the length of a contour 
  6616. n    find the point that falls at a certain distance along a contour
  6617. n    find the area enclosed by a shape’s geometry
  6618. n    find the center point of a shape’s geometry
  6619. n    find and change the bounding rectangle of a shape’s geometry
  6620. n    inset a shape’s geometry
  6621. n    determine if two shapes intersect
  6622. n    determine if one shape contains another
  6623. n    find the intersection, union, difference, and exclusion of two shapes
  6624. n    invert a shape
  6625. Finally, this chapter contains a complete reference for the geometric operations.
  6626.  
  6627. About Geometric Operations
  6628.  
  6629. The geometric operations allow you to obtain geometric information about geometric shapes and perform geometric calculations on them without having to manipulate shape geometries directly.
  6630. The geometric operations fall into five main categories:
  6631. n    operations that affect contours and contour direction
  6632. n    operations that simplify the drawing of shapes
  6633. n    operations that determine and alter basic geometric information about shapes
  6634. n    operations that test for intersection and inclusion
  6635. n    operations that perform geometric arithmetic on shapes
  6636. The next five sections discuss these categories.
  6637. Contours and Contour Direction
  6638.  
  6639. With the exception of empty, full, and point shapes, the geometric shapes are made up of contours. Line, curve, and rectangle shapes have a single contour while polygon and path shapes can have zero, one, or more contours. Every contour is defined by an ordered series of on-curve of off-curve geoemtric points or a combination of both.
  6640. For example, the geometry of a line shape contains two (on-curve) geometric points—a first point and a last point. The contour of a line shape is the line segment connecting these two points. Since the line has a first point and a last point, it also has a direction, a right side, and a left side, as shown in Figure 4-1.
  6641. Figure 4-1    Line contours
  6642.  
  6643. As another example, a path shape can have multiple contours; each path contour is defined by a series of on-curve and off-curve points. As with a line contours, each path contour has a direction, a right side, and a left side, as shown in Figure 4-2.
  6644. Figure 4-2    A path shape with two contours
  6645.  
  6646. Figure 4-2 shows the geometry of a path shape with two contours. Notice that the order of the geometric points decides which side is the left side and which side is the right side.
  6647. Each contour of a polygon or path shape has an implied line (or curve) connecting the last geoemtric point of the contour to the first geometric point of the contour. QuickDraw GX uses this implied line (or curve) when the shape fill of the polygon or path shape is the closed-frame shape fill or any of the solid shape fills.
  6648. Figure 4-2 shows the contours from Figure 4-2 with this implied line shown in gray.
  6649. Figure 4-3    A path shape with two contours
  6650.  
  6651. Notice that the right side of the first contour falls inside the area enclosed by the contour and the right side of the second contour falls outside the area enclosed by the contour. 
  6652. All contours have either a clockwise or a counterclockwise contour direction. Sometimes the contour direction of a contour is obvious, such as the contour directions of the contours in Figure 4-2. In this figure, the first contour has a clockwise contour direction and the second contour has a counterclockwise contour direction. However, sometimes the contour direction is not so obvious. Figure 4-4 gives an example.
  6653. Figure 4-4    A path whose contour direction is not immediately obvious
  6654.  
  6655. The upper half of the contour shown in Figure 4-4 seems to have a clockwise direction while the lower half of the contour seems to have a counterclockwise direction. In cases like this one, QuickDraw GX assigns an arbitrary contour direction to the entire contour. You can use the GXGetShapeDirection function, described on page 4-61, to find the contour direction that QuickDraw GX has assigned a particular contour.
  6656. QuickDraw GX uses contour direction for a number of purposes—for example, when filling shapes that have a winding shape fill. The path shape shown in Figure 4-4 contains an inner contour with the same contour direction as the contour that surrounds it. When drawing this path using a winding fill, QuickDraw GX ignores the inner contour.
  6657. Figure 4-5    A path whose inner contour has the same contour direction as its outer contour
  6658.  
  6659. To indicate that QuickDraw GX should not ignore the inner contour, you could change the shape fill to even-odd fill, or you could reverse the contour direction of the inner contour, as shown in Figure 4-4.
  6660. Figure 4-6    A path shape whose inner and outer contours have different contour direction 
  6661.  
  6662. QuickDraw GX lets you reverse a contour’s direction by reversing the order of the geometric points in the contour.
  6663. Note
  6664. QuickDraw GX always considers line shapes to have a clockwise contour direction, regardless of the order of the geometric points in the line’s geometry. Therefore, you cannot change the contour direction of line shapes. However, a line contour in a polygon or a path does have a clockwise or a counterclockwise direction (which QuickDraw GX assigns to it depending on the other contours in the shape); therefore, you can change the contour direction of line contours in polygons and paths.u
  6665. In certain situations, QuickDraw GX needs to know which side of a contour is the inside and which is the outside—for example, when drawing a geometric shape that has the inside-frame style attribute set. The default assumption is that the right side of a contour is the inside—which works well for clockwise contours but can produce suprising results with counterclockwise contours. The auto-inset style attribute indicates that QuickDraw GX should find the true inside for each contour of a shape, rather than assuming the right side is the inside. The true inside of a contour is defined to be the right side of the contour if the contour direction is clockwise and the left side of a contour if the contour direction is counterclockwise. 
  6666. You can find more information about the inside-frame style attribute and the auto-inset style attribute in Chapter 3, “Geometric Styles,” in this book.
  6667. The section “Determining and Reversing Contour Direction” beginning on page 4-21 contains programming examples relating to contour direction.
  6668. Reducing and Simplifying Shape Geometries
  6669.  
  6670. QuickDraw GX allows you to change shape geometries to simpler forms. You can reduce the number of geometric points in a shape by removing unnecessary ones. You can also simplify a shape’s geometry by removing unnecessary contour breaks, eliminating crossed and overlapping contours, and even simplifying the shape’s shape type, if possible.
  6671. Figure 4-7 shows the difference between reducing a shape’s geometry and simplifying a shape’s geometry.
  6672. Figure 4-7    Effects of reducing and simplifying shape geometries
  6673.  
  6674. In this figure, the polygon geometry has two unnecessary geoemtric points, which are removed in the reduced polygon. Since the polygon is actually a square, simplifying this polygon removes the geometric points unnecessary to describe this shape and converts the polygon geoemtry to the simplest type of geometry necessary—which in this case isa rectangle geometry.
  6675. The path geometry in the lower part of Figure 4-7 has a crossed contour, but no unnecessary geometric points. Reducing this path results in the same path geometry, whereas simplifing this path reorders the geometric points and breaks the geometry into two path contours so that no contour crossing occurs. Although this might not seem like a simplification, removing crossed contours does result in more predictable drawing results, as shown in Figure 4-8.
  6676. Figure 4-8    How simplifying a shape can produce more predictable results when drawing
  6677.  
  6678. Figure 4-8 shows the path geometry from Figure 4-7. When this path is drawn with an pen width of 10 and the inside-frame style attribute set, the upper half of the path is inset, but the lower half of the path is outset, because of the crossed contour. Simplifying the shape uncrosses the contour, which results in both halves of the path shape being inset when drawn.
  6679. For more examples of th effect of simplifying shapes on drawing, see the section “Simplifying Shapes” beginning on page 4-29, as well as in the pen placement examples in Chapter 3, “Geometric Styles,” in this book. 
  6680. The Primitive Form of Shape Geometries
  6681.  
  6682. QuickDraw GX provides a mechanism for incorporating the stylisticvariations contained in a style object directly intothe geometry of a shape object. This mechanism is the GXPrimitiveShape function. When the geometry of a shape has its stylistic variations incorporated into it, it is said to be in primitive form. Shapes in primitive form include
  6683. n    empty shapes and full shapes, which are described in the Chapter 2, “Geometric Shapes”
  6684. n    filled rectangle, polygon, and path shapes, which are also described in Chapter 2, “Geometric Shapes”
  6685. n    hairline framed shapes, which are described in Chapter 3, “Geometric Styles”
  6686. n    glyph shapes, which are described in Inside Macintosh: QuickDraw GX Typography
  6687. Figure 4-9 shows a simple example of the GXPrimitiveShape function. This figure shows a line geometry as drawn with a pen width of 10.0. Converting this line shape to its primitive form results in a rectangle shape with an even-odd fill; the pen width has been incorporated into the geometry of the shape.
  6688. Figure 4-9    Simple example of the GXPrimitiveShape function
  6689.  
  6690. Figure 4-9 shows a more involved example—a line shape dashed with diamond-shaped polygons. Converting this line shape to its primitive form results in a polygon shape with multiple contours—one contour for each dash.
  6691. Figure 4-10    More involved example of the GXPrimitiveShape function
  6692.  
  6693. Notice that, even though the geometry of the shape has changed significantly, the shape appears the same when drawn. Also notice that the GXPrimitiveShape function affects only the shape type, shape geometry, and shape fill of a shape—it does not affect the shape’s associated style object.
  6694. For more information about primitve shapes and when you might use them, see Chapter 3, “Geometric Styles.”
  6695. For programming examples illustrating shapes in their primitive form, see “Converting a Shape to Primitive Form” beginning on page 4-34.
  6696. Geometric Information
  6697.  
  6698. QuickDraw GX lets you calculate specific geometric information about a shape, or about the contour of a shape. You can
  6699. n    find the length of all of a shape’s contours or of a particular contour of a shape
  6700. n    locates the point that falls at a given distance along a particular contour of a shape
  6701. n    calculates the area contained by the contours of a shape’s geometry or by a particular contour of a shape’s geometry
  6702. n    find the center point of a shape or of a particular contour of a shape
  6703. n    find the bounding rectangle of a shape
  6704. Figure 4-11 illustrates the geometric information you can obtain about a shape.
  6705. Figure 4-11    Geometric information available about a path shape
  6706.  
  6707. QuickDraw GX also allows you to set the bounding rectangle of a shape, and therefore move and scale the shape, as shown in Figure 4-12.
  6708. Figure 4-12    A path shape resized by changing its bounding rectangle
  6709.  
  6710. For examples of obtaining geometric information about shapes, see “Finding Geometric Information About a Shape” beginning on page 4-36. 
  6711. For examples of setting the bounding rectangle of a shape, see “Setting a Shape’s Bounding Rectangle” beginning on page 4-42.
  6712. Intersection and Inclusion
  6713.  
  6714. QuickDraw GX allows you to determine if the area contained by the contours of one shape intersect the area contained by the contours of another shape. You can also determine if one shape’s area contains the area of another shape.
  6715. In particular, you can
  6716. n    determine if a point intersects the area contained by a rectangle
  6717. n    determine if the area contained by the contours of a shape intersects the area contained by a rectangle
  6718. n    determines if the areas of two shapes intersect
  6719. Figure 4-13 shows the results of testing to see whether pairs of different geometric shapes intersect. In this figure, a filled rectangle shape is tested for intersection with both a framed path and a filled path, and a filled path is tested for intersection with a filled polygon.
  6720. Figure 4-13    Testing shapes for intersection
  6721.  
  6722. QuickDraw GX also allows you to determine whether or not
  6723. n    one rectangle contains another
  6724. n    a rectangle contains the area covered by a shape
  6725. n    the area covered by one shape contains the area covered by another shape.
  6726. Figure 4-14 shows the results of testing pairs of shapes to see if one shape contains another.
  6727. Figure 4-14    Testing whether one shape contains another
  6728.  
  6729. Notice the first diagram in the third row of Figure 4-14. A shape does not contain another shape if it merely surrounds the other shape; the area covered by the first shape as drawn must contain the area of the second shape as drawn.
  6730. Note
  6731. QuickDraw GX defines empty shapes as touching no shapes and full shapes as touching any shape except an empty shape. QuickDraw GX also defines full shapes as containing any shape and empty shapes as being contained by any shape.u
  6732. For examples of testing shapes for intersection, see “Determining Whether Two Shapes Touch” beginning on page 4-47. 
  6733. For examples of testing shapes for inclusion, see “Determining Whether One Shape Contains Another” beginning on page 4-51.
  6734. Geometric Arithmetic
  6735.  
  6736. QuickDraw GX provides six different arithmetic operations that you can perform on geometric shapes. These operations are: intersection, union, difference, reverse difference, exclusion. With these operations, you can
  6737. n    find the intersection of two rectangles
  6738. n    find the union of two rectangles
  6739. n    find the area common to two shapes
  6740. n    find the combined area of by two shapes
  6741. n    find the area covered by one shape that is not also covered by another
  6742. n    find the area covered by one shape or another, but not both
  6743. Figure 4-15 illustrates these arithmetic operations.
  6744. Figure 4-15    Geometric arithmetic with two filled shapes
  6745.  
  6746. Figure 4-15 shows geometric arithmetic with two filled shapes. You can also perform some geometric arithmetic on a filled shape and a framed shape, as shown in Figure 4-15.
  6747. Figure 4-16    Geometric arithmetic with a framed shape and a filled shape
  6748.  
  6749. QuickDraw GX also allows you to find the inversion of a shape—the area not covered by a shape. Figure 4-15 illustrates geometic inversion.
  6750. Figure 4-17    Geometric inversion
  6751.  
  6752. The inverted shape extends to the limits of its clip shape or the limits of the view port to which it is drawn.
  6753. For examples of geometric arithmetic, see “Performing Geometric Arithmetic With Shapes” beginning on page 4-53. 
  6754.  
  6755.  
  6756. Using Geometric Operations
  6757.  
  6758. This section shows you how to apply geometric operations to shapes. In particular, this section shows you how to:
  6759. n    determine and change the direction of a shape’s contours
  6760. n    break a contour into multiple contours
  6761. n    eliminate unnecessary points from a shape’s geometry
  6762. n    eliminate contour crossings and unnecessary internal contour loops from a shape’s geometry
  6763. n    incorporate style information from a style object into the geometry of a shape
  6764. n    obtain geometric information about a shape (such as the length of a contour or the area covered by the shape)
  6765. n    determine and change the bounding rectangle of a shape
  6766. n    inset a shape
  6767. n    determine if two shapes intersect
  6768. n    determine if one shape contains another
  6769. n    peform geometric arithmetic on shapes (such as intersection, union, difference, and exclusion)
  6770. Many of the sample functions in this section create geometric shapes, and to do so, they specify geometric points for the shapes’ geometries. Since a geometric point contains two fixed-point values, the sample functions in this section must convert integer constants to fixed-point constants when specifying a geometric point. QuickDraw GX provides the GXIntToFixed macro, which performs this conversion by shifting the integer value 16 bits to the left:
  6771. #define GXIntToFixed(a)  ((fixed) (a) << 16)
  6772. QuickDraw GX also provides the ff macro as a convenient alias:
  6773. #define ff(a)  GXIntToFixed(a)
  6774. The ff macro is used throughout this section.
  6775. Determining and Reversing Contour Direction
  6776.  
  6777. The contours of geoemtric shapes have contour direction: either clockwise or counterclockwise, as described in “Contours and Contour Direction” beginning on page 4-4. QuickDraw GX allows you to determine the contour direction of a specific contour of a shape and also allows you to change the direction of a shape’s contour by reversing the order of the geometric points in the geometry defining the contour.
  6778. The sample function in Listing 4-1 creates a polygon shape with two contours—one having a clockwise contour direction and the other having a counterclockwise contour direction.
  6779. Listing 4-1    Creating a polygon shape with two contours having opposite contour directions
  6780.  
  6781. void CreateConcentricTriangles(void)
  6782. {
  6783.     gxShape twoTriangles;
  6784.  
  6785.     long  twoTrianglesGeometry[] = {2, /* number of contours */
  6786.                                                   3, /* number of points */
  6787.                                                  ff(50), ff(200),
  6788.                                                  ff(110), ff(100),
  6789.                                                 ff(170), ff(200), 
  6790.                                                 3, /* number of points */
  6791.                                                 ff(90), ff(178),
  6792.                                                 ff(130), ff(178),
  6793.                                                 ff(110), ff(145)};
  6794.     
  6795.     twoTriangles = GXNewPolygons((gxPolygons *) 
  6796.                                            twoTrianglesGeometry);
  6797.     GXSetShapeFill(twoTriangles, gxWindingFill);
  6798.     GXDrawShape(twoTriangles);
  6799.     GXDisposeShape(twoTriangles);
  6800. }
  6801. The result of this sample function is shown in Figure 4-18. 
  6802. Figure 4-18    A polygon shape whose two contours have opposite contour directionsr
  6803.  
  6804. QuickDraw GX provides the GXGetShapeDirection function to allow you to determine the contour direction of a specific contour in a shape. This function takes two parameters: the first parameter is a reference to the shape and the second parameter is the index of the contour whose contour direction you want to find. In the example from Listing 4-1, the first contour (the outer contour) has a clockwise contour direction. Calling the function
  6805. GXGetShapeDirection(twoTriangles, 1)
  6806. returns the constant gxClockwiseDirection.
  6807. The second contour (the inner contour) has a counterclockwise direction. Calling the function
  6808. GXGetShapeDirection(twoTriangles, 2)
  6809. returns the constant gxCounterclockwiseDirection.
  6810. You can reverse the direction of a contour by reversing the order of the contour’s geometric points. For this purpose, QuickDraw GX provides the GXReverseShape function. This function also takes two parameters: a reference to the shape and the index of the contour to reverse. Specifying 0 as the number of the contour to reverse causes the GXReverseShape function to reverse all the contours of a shape. For example, adding you can add the following function call to the sample function in Listing 4-1:
  6811. GXReverseShape(twoTriangles, 0);
  6812. The result is shown in Figure 4-19.
  6813. Figure 4-19    A polygon shape with the direction of both contours reversed
  6814.  
  6815. Since both contours are reversed in this example, the shape appears the same when drawn as it did before the contours were reversed.
  6816. However, reversing only the inner contour of this polygon by calling
  6817. GXReverseShape(twoTriangles, 2);
  6818. results in the polygon shown in Figure 4-20.
  6819. Figure 4-20    A polygon shape with the direction of the inner contour reversed
  6820.  
  6821. Reversing the contour of a shape by calling the GXReverseShape function almost always changes the result of the GXGetShapeDirection function. One important exception, however, is that line shapes always have a clockwise direction. The order of a line shape’s geometric points does not affect the result of the GXGetShapeDirection function.
  6822. For a discussion of contour direction, see “Contours and Contour Direction” beginning on page 4-4.
  6823. For more information about the GXGetShapeDirection function, see page 4-61. For more information about the GXReverseShape function, see page 4-63.
  6824. Breaking Shape Contours
  6825.  
  6826. Polygon and path shapes can contain many contours. Each contour of a polygon shape can be made up of many lines and each contour of a pathshape can be made up of many lines and curves.
  6827. QuickDraw GX provides a method for breaking a single contour of a polygon or path shape into two contours at a specified geometric point in the original contour.
  6828. As an example, the sample function in Listing 4-2 creates a path shape with a single contour. This contour contains six geometric points and is made up of a curve, a line, and another curve.
  6829. Listing 4-2    Creating a path shape with a single contour
  6830.  
  6831. void CreateSingleContourPath(void)
  6832. {
  6833.     gxShape  aPathShape;
  6834.  
  6835.     static long oneContourGeometry[] = {1,
  6836.                                                      6,
  6837.                                                      0x48000000,
  6838.                                                      ff(100), ff(150),
  6839.                                                      ff(50), ff(100),
  6840.                                                      ff(100), ff(50),
  6841.                                                      ff(200), ff(50),
  6842.                                                      ff(250), ff(100),
  6843.                                                      ff(200), ff(150)};
  6844.  
  6845.     aPathShape = GXNewPaths((gxPaths *) oneContourGeometry);
  6846.     GXSetShapeFill(aPathShape, gxClosedFrameFill);
  6847.  
  6848.     GXDrawShape(aPathShape);
  6849.     GXDisposeShape(aPathShape);
  6850. }
  6851. The result of this function is shown in Figure 4-21.
  6852. Figure 4-21    A path shape with a single contour
  6853.  
  6854. The GXBreakShape function allows you to break a single contour into two contours at a specified geometric point. Adding the function call
  6855. GXBreakShape(aPathShape, 4);
  6856. to the sample function in Listing 4-2 breaks the single contour of the path shape into two contours at the fourth geometric point, as shown in Figure 4-22.
  6857. Figure 4-22    A path shape broken into two contours
  6858.  
  6859. After the call to the GXBreakShape function, the path shape has two contours, each with three geometric points. Calling the function 
  6860. GXCountShapeContours(aPathShape);
  6861. returns the value 2.
  6862. In addition to breaking the contours of polygon and path shapes, you can also use the GXBreakShape function to break line shapes and curve shapes. For example, if the variable aLine references a line shape, the function call:
  6863. GXBreakShape(aLine, 1);
  6864. converts the line shape to a polygon shape with two contours. The first contour is empty (that is, it has no geometric points) and the second contour is the original line. Calling the function
  6865. GXCountShapeContours(aLine);
  6866. returns the value 2.
  6867. For a discussion of contours, geometric points, and the GXCountShapeContours function, see Chapter 2, “Geometric Shapes,” in this book.
  6868. You can also use the GXSetPolygonParts, GXSetPathParts, and GXSetShapeParts functions to break a shape’s contours. These functions are also described in Chapter 2, “Geometric Shapes,” in this book.
  6869. For more information about the GXBreakShape function, see page 4-64.  
  6870. Eliminating Unnecessary Geometric Points
  6871.  
  6872. There are many ways in which polygon and path shapes can contain more geometric points than necessary to describe their underlying geometry. Two common examples are:
  6873. n    duplicate points—sequential points with the same coordinates
  6874. n    colinear points—points that lie in a straight line between a preceding point and subsequent point
  6875. The sample function in Listing 4-3 creates a polygon shape with a single contour that has six geometric points, two of which are unnecessary.
  6876. Listing 4-3    Creating a polygon with redundant geometric points
  6877.  
  6878. void ReduceUnnecessaryPoints(void)
  6879. {
  6880.     gxShape  squareShape;
  6881.  
  6882.     static long paddedSquareGeometry[] = {1,
  6883.                                                       6,
  6884.                                                       ff(50), ff(50),
  6885.                                                       ff(100), ff(50),  
  6886.                                                       ff(150), ff(50),  
  6887.                                                       ff(150), ff(150),  
  6888.                                                       ff(150), ff(150),  
  6889.                                                       ff(50), ff(150)};
  6890.  
  6891.  
  6892.     squareShape = GXNewPolygons((gxPolygons *) 
  6893.                                          &paddedSquareGeometry);
  6894.     GXSetShapeFill(squareShape, gxEvenOddFill);
  6895.  
  6896.     GXDrawShape(squareShape);
  6897.     GXDisposeShape(squareShape);
  6898. }
  6899. The resulting polygon shape is shown in Figure 4-23.
  6900. Figure 4-23    A polygon shape with unnecessary geometric points
  6901.  
  6902. QuickDraw GX provides the GXReduceShape function so you can eliminate unnecessary duplicate and colinear points. The GXReduceShape function takes two parameters: a reference to the shape containing the contour whose unnecessary geometric points you want to eliminate and an index specifying the contour itself. If you supply the value 0 for the second parameter, the GXReduceShape function eliminates unnecessary geometric points from all the contours of a shape. 
  6903. As an example, adding the function call
  6904. GXReduceShape(squareShape, 0);
  6905. to the sample function in Listing 4-3 results in the polygon shape shown in Figure 4-24.
  6906. Figure 4-24    A poygon shape with the unnecessary geometric points removed
  6907.  
  6908. The unnecessary duplicate geometric point and the unnecessary colinear geometric point are gone, but the polygon still appears the same when drawn. Although the resulting geometry could be described by a rectangle shape, the shape in this example remains a polygon shape. The GXReduceShape function does not convert the shape type of the original shape. (However, the GXSimplifyShape function, shown in the next section, does convert shape type, when possible.)
  6909. The GXReduceShape function considers two points to be duplicate points if they are within the distance from each other specified by the curve error property of the shape’s style object. See Chapter 3, “Geometric Styles,” in this book for a discussion of curve error.
  6910. For a discussion of geometric points, see Chapter 2, “Geometric Shapes,” in this book.
  6911. For more information about the GXReduceShape function, see page 4-66.
  6912. Simplifying Shapes
  6913.  
  6914. In addition to unnecessary geometric points, there are other aspects of shape geometries that complicate the definition and drawing of a shape. Some examples are:
  6915. n    an unnecessary contour breaks, where an open-framed contour ends on the same point where the subsequent contour begins
  6916. n    a crossed contour, where a contour crosses over itself or another contour of the same shape
  6917. n    overlapping contours, where inner contour loops have the same contour direction as the contour that contains them
  6918. The sample function in Listing 4-4 creates a polygon shape with a single contour that crosses over itself.
  6919. Listing 4-4    Creating a polygon shape with a crossed contour
  6920.  
  6921. void CreateHourglassPolygon(void)
  6922. {
  6923.     gxShape aPolygonShape;
  6924.  
  6925.     static long hourglassGeometry[] = {1,
  6926.                                                   4,
  6927.                                                   ff(50), ff(50),
  6928.                                                   ff(150), ff(50),
  6929.                                                   ff(50), ff(150),
  6930.                                                   ff(150), ff(150)};
  6931.  
  6932.     aPolygonShape = GXNewPolygons((gxPolygons *) 
  6933.                                             hourglassGeometry);
  6934.     GXSetShapeFill(aPolygonShape, gxClosedFrameFill);
  6935.     
  6936.     GXDrawShape(aPolygonShape);
  6937.     GXDisposeShape(aPolygonShape);
  6938. }
  6939. The resulting polygon shape is shown in Figure 4-25.
  6940. Figure 4-25    A polygon shape with a crossed contour
  6941.  
  6942. QuickDraw GX provides the GXSimplifyShape function so you can eliminate unnecessary contour breaks, crossed contours, and overlapping contours. This function takes one parameter: a reference to the shape you want to simplify.
  6943. As an example, adding the function call
  6944. GXSimplifyShape(aPolygonShape);
  6945. to the sample function in Listing 4-4 creates the polygon shown in Figure 4-26.
  6946. Figure 4-26    A polygon shape with no crossed contours
  6947.  
  6948. Notice that although this polygon shape is simplified, it contains more geometric points than the original polygon. Extra geometric points are required to eliminate the crossed contour. 
  6949. (*** Add note about second contour ***)
  6950. As another example, the sample function in Listing 4-5 creates a path shape with two concentric contours: an outer contour and an inner contour, both of which have a clockwise contour direction.
  6951. Listing 4-5    Creating a path with two clockwise contours
  6952.  
  6953. void CreateConcentricPaths(void)
  6954. {
  6955.     gxShape aPathShape;
  6956.  
  6957.     static long                twoCircleGeometry[] = {2, /* # of contours */
  6958.                                                   4, /* # of points */
  6959.                                                   0xFF000000,
  6960.                                                   ff(50), ff(50),    
  6961.                                                   ff(150), ff(50), 
  6962.                                                   ff(150), ff(150),  
  6963.                                                   ff(50), ff(150),
  6964.                                                   4, /* # of points */
  6965.                                                   0xFF000000,
  6966.                                                   ff(65), ff(65),
  6967.                                                   ff(135), ff(65),
  6968.                                                   ff(135), ff(135),
  6969.                                                   ff(65), ff(135)};
  6970.  
  6971.  
  6972.     aPathShape = GXNewPaths((gxPaths *) twoCircleGeometry);
  6973.     GXSetShapeFill(aPathShape, gxEvenOddFill);
  6974.     
  6975.     GXDrawShape(aPathShape);
  6976.     GXDisposeShape(aPathShape);
  6977. }
  6978. Figure 4-27 shows the result of this sample function.
  6979. Figure 4-27    A path shape with two concentric clockwise contours
  6980.  
  6981. Applying the GXSimplifyShape function to the path shape in Figure 4-27 reverses the contour direction of the inner contour, so that it is no longer an overlapping contour with the same contour direction. The result is shown in Figure 4-28.
  6982. Figure 4-28    A path shape with two concentric contours with opposite contour direction
  6983.  
  6984. However, imagine that the path shape defined in Listing 4-5 originally had a winding fill, as shown in Figure 4-27.
  6985. Figure 4-29    A path shape with two concentric clockwise contours drawn with winding shape fill
  6986.  
  6987. In this case, the GXSimplifyShape function removes the inner contour entirely, as it is not necessary to describe the shape as drawn. The result is shown in Figure 4-27.
  6988. Figure 4-30    A path shape simplified to a single clockwise contour
  6989.  
  6990. The GXSimplifyShape function can change the shape type of a shape, as well the geometry of shape, if the shape can be expressed by a simpler shape type. For example, a polygon shape might be converted to a rectangle shape or a line shape, if possible. Similarly, a path shape might be converted to a polygon shape if it has no off-curve control points.
  6991. For a discussion of shape fills and contour direction, see Chapter 2, “Geometric Shapes,” in this book.
  6992. For more information about the GXSimplifyShape function, see page 4-67. 
  6993. Converting a Shape to Primitive Form
  6994.  
  6995. QuickDraw GX requires that certain shapes (such as cap shapes, join shapes, dash shapes, pattern shapes, and clip shapes) be in primitive form—that is, they must have all of their style modifications incorporated into their geometries. Before you set a cap shape, join shape, dash shape, and so on, you must ensure that the shape is in primitive form.
  6996. As an example of converting a shape to primitive form, the sample function in Listing 4-6 creates a polygon shape that is not in primitive form. The polygon has one contour, a closed-frame shape fill, and a pen width of 15.
  6997. (*** Need new constants. ***)
  6998. Listing 4-6    Creating an hourglass polygon shape with a thick pen width
  6999.  
  7000. void CreateHourglassPolygon(void)
  7001. {
  7002.     gxShape aPolygonShape;
  7003.     gxJoinRecord theJoinRecord;
  7004.  
  7005.     static long hourglassGeometry[] = {1,
  7006.                                                   4,
  7007.                                                   ff(50), ff(50),
  7008.                                                   ff(150), ff(50),
  7009.                                                   ff(50), ff(150),
  7010.                                                   ff(150), ff(150)};
  7011.  
  7012.  
  7013.     aPolygonShape = GXNewPolygons((gxPolygons *)
  7014.                                            hourglassGeometry);
  7015.     GXSetShapeFill(aPolygonShape, gxClosedFrameFill);
  7016.     GXSetShapePen(aPolygonShape, ff(15));
  7017.     
  7018.     theJoinRecord.attributes = gxSharpJoin;
  7019.     theJoinRecord.join = nil;
  7020.     theJoinRecord.miter = gxPositiveInfinity;
  7021.     GXSetShapeJoin(aPolygonShape, &theJoinRecord);
  7022.     
  7023.     GXDrawShape(aPolygonShape);
  7024.     GXDisposeShape(aPolygonShape);
  7025. }
  7026. The result of this sample function is shown in Figure 4-31.
  7027. Figure 4-31    A hourglass-shaped polygon with a thick border
  7028.  
  7029. The polygon shape defined in Listing 4-6 is not in primitive form because an element of the polygon’s style (the pen width) is not incorporated into the polygon’s geometry.
  7030. QuickDraw GX provides the GXPrimitiveShape function so you can incorporate the elements of a shape’s style into the shape’s geometry. For example, adding the function call
  7031. GXPrimitiveShape(aPolygonShape);
  7032. to the sample function in Listing 4-6 creates the polygon shown in Figure 4-32.
  7033. Figure 4-32    A polygon shape with style information incorporated into its geometry
  7034.  
  7035. As shown in Figure 4-32, the GXPrimitiveShape function has incorporated the pen width into the geometry of the polygon; the resulting polygon has two contours whereas the orignal had one, and the resulting polygon has a winding fill instead of a closed-frame fill.
  7036. Notice that the primitive form of this polygon is not simplified because the GXPrimitiveShape function does not simplify its result. You can simplify the result of this function by calling
  7037. GXSimplifyShape(aPolygonShape);
  7038. Figure 4-33 shows the resulting shape—the primitive form of the polygon with no crossed or overlapping contours.
  7039. Figure 4-33    The primitive form of the polygon shape after simplification
  7040.  
  7041. The polygon shape now has three contours—which do not cross or overlap—and yet it appears the same as the original polygon shape when drawn.
  7042. For a discussion of style modifications and more examples of the GXPrimitiveShape function, see Chapter 3, “Geometric Styles,” in this book.
  7043. For more information about the GXPrimitiveShape function, see page 4-69. 
  7044. Finding Geometric Information About a Shape
  7045.  
  7046. QuickDraw GX provides a number of functions that allow you to determine geometric information about a shape, such as the length of a contour or the area covered by a shape.
  7047. To illustrate these functions, the sample function in Listing 4-7, creates a path shape with two concentric contours, the outer contour having a clockwise contour direction and the inner contour having a counterclockwise contour direction.
  7048. Listing 4-7    Creating a pathshape with two contours having opposite contour directions
  7049.  
  7050. void CreateConcentricCircles(void)
  7051. {
  7052.     gxShape aPathShape;
  7053.  
  7054.     static long                twoCircleGeometry[] = {2, /* number of contours */
  7055.                                                   4, /* number of points */
  7056.                                                   0xFF000000,
  7057.                                                   ff(50), ff(50),   /* off */
  7058.                                                   ff(150), ff(50),  /* off */
  7059.                                                   ff(150), ff(150), /* off */
  7060.                                                   ff(50), ff(150),  /* off */
  7061.                                                   4, /* number of points */
  7062.                                                   0xFF000000,
  7063.                                                   ff(65), ff(135),  /* off */
  7064.                                                   ff(135), ff(135), /* off */
  7065.                                                   ff(135), ff(65),  /* off */
  7066.                                                   ff(65), ff(65)};  /* off */
  7067.  
  7068.  
  7069.     aPathShape = GXNewPaths((gxPaths *) twoCircleGeometry);
  7070.  
  7071.     GXDrawShape(aPathShape);
  7072.     GXDisposeShape(aPathShape);
  7073. }
  7074. The resulting shape geometry is shown in Figure 4-34.
  7075. Figure 4-34    A path with an outer clockwise contour and an inner counterclockwise contour
  7076.  
  7077. QucikDraw GX provides the GXGetShapeLength function so you can measure the length of a contour. This function takes three parameters: a reference to the shape containing the contour you want to measure, an index indicating which contour you want to measure, and a pointer to a variable of type gxWide to store the result.
  7078. For example, if you add the declaration
  7079. gxWide         length;
  7080. and the function call
  7081. GXGetShapeLength(aPathShape, 1, &length);
  7082. to the sample function in Listing 4-7, the value returned in the length parameter is approximately 322.543, which is the length (the circumference) of the outer contour.
  7083. QuickDraw GX also provides the GXShapeLengthToPoint function that allows you to calculate the position of the point that falls at a specified distance along a contour. This function also calculates the tangent of the contour at that point.
  7084. As an example, adding the function cal
  7085. GXShapeLengthToPoint(aPathShape, 1, ff(120), 
  7086.                            &thePoint, &theDirection);
  7087. to the sample function in Listing 4-7 determines the point that falls along the first contour at a distance of 120.0 points from the start of the contour, and stores the resulting point in the thePoint parameter. Also, in the theDirection parameter, this function stores a tangent vector indicating the direction of the contour at that point.
  7088. The result of this function is shown in Figure 4-35.
  7089. Figure 4-35    A specified point on a path contour
  7090.  
  7091. QuickDraw GX also provides functions for finding the bounding rectangle of a shape and the center point of a shape. The bounding rectangle is the smallest rectangle that contains the shape. The center point of a shape is not merely the center of the shape’s bounding rectangle; rather it is the “center of gravity” of a shape. The center point is defined to be the point such that half of a shape’s area lies above the point and half of the shapes area lies below the point; similarly, half of the shape’s area lies to the left of the point and half of the shapes area lies to the right of the point.
  7092. You can us the GXGetShapeBounds function to find the bounding rectangle of a shape. As an example, if you apply the function
  7093. GXGetShapeBounds(aPathShape, 0, &theBounds);
  7094. to the path shape from Listing 4-7, ther result is a rectangle with the coordinates (50.0, 50.0, 150.0, 150.0). Similarly, if you apply the function
  7095. GXGetShapeCenter(aPathShape, 0, &thePoint);
  7096. to the same path shape, the result is the point: (100.0, 100.0).
  7097. The results of these functions is depicted in Figure 4-36.
  7098. Figure 4-36    Finding the bounding rectangle and the centerpoint of a path
  7099.  
  7100. If you move the inner contour of the path shape to right, the center point moves to the right as well, effectively moving with the combined “center of gravity” of the two contours, as shown in Figure 4-36.
  7101. Figure 4-37    Finding the center point of two contours
  7102.  
  7103. Notice that the center point lies somewhere between the center of the outer contour and the center of the inner contour. Since the outer contour covers more area, it exerts more influence over the location of the center point than the inner contour. (*** Is this true? It doesn’t look like it in the figure. ***)
  7104. QuickDraw GX provides the GXGetShapeArea function so you can determine the area covered by a shape.
  7105. With the path shape from Listing 4-7, applying the function
  7106. GXGetShapeArea(aPathShape, 1, &theArea);
  7107. results in the value 4250.0. This value represents the area of the outer contour minus the area of the inner contour, as shown in Figure 4-38.
  7108. Figure 4-38    Finding the area of a shape
  7109.  
  7110. In effect, the function finds the area covered by the shape as if it were filled with the winding shape fill.
  7111. Therefore, if you reverse the direction of the inner contour of this path with the function call
  7112. GXReverseShape(aPathShape, 2);
  7113. then the function call
  7114. GXGetShapeArea(aPathShape, 1, &theArea);
  7115. results in the value 12416.6666. This value represents the area of the outer contour plus the area of the inner contour—the area covered by the inner contour is counted twice.
  7116. The area included in this calculation is depicted in Figure 4-39.
  7117. Figure 4-39    The sum of all the contour areas of a path shape
  7118.  
  7119. Note that the GXGetShapeArea function does not consider the shape fill when calculating area—it includes this overlapping area twice whether the shape fill is winding fill, even-odd fill, open-frame fill, or closed-frame fill.
  7120. You can correct this calculation by calling the GXSimplifyShape function first. For example, if you set the shape fill to winding fill with the function call
  7121. GXSetShapeFill(aPathShape, gxWindingFill);
  7122. and then call the GXSimplifyShape function:
  7123. GXSimplifyShape(aPathShape);
  7124. the GXSimplifyShape function removes the inner contour, as shown in Figure 4-40.
  7125. Figure 4-40    A simplified path
  7126.  
  7127. Once this inner contour is removed, you can call the GXGetShapeArea function, and the area of the original outer contour (8333.3333) is returned.
  7128. For more information about the GXGetShapeLength function, see page 4-71. For more information about the GXShapeLengthToPoint function, see page 4-72. 
  7129. For more information about the GXGetShapeBounds function, see page 4-76. For more information about the GXGetShapeCenter function, see page 4-73. 
  7130. For more information about the GXGetShapeArea function, see page 4-74.
  7131. Setting a Shape’s Bounding Rectangle
  7132.  
  7133. The GXGetShapeBounds function, illustrated in the previous section, allows you to determine the bounding rectangle of a shape. Similarly, the GXSetShapeBounds function allows you to alter the bounding rectangle of a shape, thereby scaling the shape to a new size and moving it to a new location.
  7134. As an example, the sample function in Listing 4-8 creates a path with a single circular contour.
  7135. Listing 4-8    Creating a circular path
  7136.  
  7137. void CreateCircularPath(void)
  7138. {
  7139.     gxShape                   aPathShape;
  7140.  
  7141.     static long                 circularGeometry[] = {1, /* # of contours */
  7142.                                                   4, /* # of points */
  7143.                                                   0xFF000000,
  7144.                                                   ff(50), ff(50),   /* off */
  7145.                                                   ff(150), ff(50),  /* off */
  7146.                                                   ff(150), ff(150), /* off */
  7147.                                                   ff(50), ff(150)}; /* off */
  7148.  
  7149.  
  7150.     aPathShape = GXNewPaths((gxPaths *) circularGeometry);
  7151.  
  7152.     GXDrawShape(aPathShape);
  7153.     GXDisposeShape(aPathShape);
  7154. }
  7155. The result of this function is shown in Figure 4-41.
  7156. Figure 4-41    A circular path
  7157.  
  7158. The bounding rectangle of this shape, which you can determine by calling
  7159. GXGetShapeBounds(aPathShape, 0, &theBounds);
  7160. is (50.0, 50.0, 150.0, 150.0). You can move and resize this shape by declaring a new bounding rectangle
  7161. gxRectangle newBounds = {ff(60), ff(60), ff(110), ff(110)};
  7162. and then calling the function
  7163. GXSetShapeBounds(aPathShape, &newBounds);
  7164. The geometry of the altered shape is centered around the point (85.0, 85.0) and is smaller than the original shape, as showin in Figure 4-42.
  7165. Figure 4-42    A smaller circular path
  7166.  
  7167. In this example, the GXSetShapeBounds function actually alters the geometry of the original shape. If you call
  7168. GXGetShapeArea(aPathShape, 0, &theArea);
  7169. the area returned in the theArea parameter reflects the area of new, smaller, geometry.
  7170. However, if you set the gxMapTransformShape shape attribute of the path shape before setting the shape bounds, QuickDraw GX moves and resizes the shape by changing the information in the shape’s transform—not by changing the geometric points of the shape’s geometry. In this case, calling the GXGetShapeArea function, which examines only a shape’s geometry and ignore its transform results in the area of the original geometry. The result of declaring a new bound rectangle and then calling
  7171. GXSetShapeAttributes(aPathShape,
  7172.                             GXGetShapeAttributes(aPathShape) | 
  7173.                              gxMapTransformShape);
  7174. GXSetShapeBounds(aPathShape, &newBounds);
  7175. GXGetShapeArea(aPathShape, 0, &theArea);
  7176. is shown in Figure 4-43.
  7177. Figure 4-43    A path shape with a transform mapping
  7178.  
  7179. For more information about the GXSetShapeBounds function, see page 4-77. For more information about the GXGetShapeBounds function, see page 4-76.
  7180. For more information about the gxMapTransformShape shape attribute, see the chapter “Shape Objects” and the chapter “Transform Objects” of Inside Macintosh: QuickDraw GX Objects.
  7181. Insetting Shapes
  7182.  
  7183. Whereas the GXSetShapeBounds function, illustrated in the previous section, provides a way to scale a shape, the GXInsetShape function provides a way to resize a shape relative to its original contours.
  7184. The sample function in Listing 4-9 creates a curve shape to use as an example.
  7185. Listing 4-9    Creating a tight curve shape
  7186.  
  7187. void CreateATightCurve(void)
  7188. {
  7189.     gxShape curveShape;
  7190.  
  7191.     const gxCurve tightCurveGeometry = {ff(90), ff(200), 
  7192.                                                    ff(110), ff(0),  
  7193.                                                    ff(120), ff(200)};
  7194.  
  7195.  
  7196.     curveShape = GXNewCurve(&tightCurveGeometry);
  7197.     GXSetShapeFill(curveShape, gxOpenFrameFill);
  7198.  
  7199.     GXDrawShape(curveShape);    
  7200.     GXDisposeShape(curveShape);    
  7201. }
  7202. The result of this function is shown in Figure 4-44.
  7203. Figure 4-44    A tight curve
  7204.  
  7205. If you apply
  7206. GXInsetShape(curveShape, ff(10));
  7207. to this curve, the function insets the curve a distance of 10.0 points from the original geometry, as shown in Figure 4-45. The resulting shape is a path shape with 16 geometric points.
  7208. Figure 4-45    An inset curve shape  with 16 geometric points
  7209.  
  7210. You can use a shape’s curve error to control the number of geometric points in the shape resulting from the inset operation. The result of the GXInsetShape function has no two consecutive points closer than the distance indicated by the shape’s curve error.
  7211. The GXInsetShape function considers the contour direction when calculating an inset contour. For example, if you use 
  7212. GXReverseShape(curveShape, 1);
  7213. to reverse the direction of the curve from Listing 4-9 before you inset the curve, the resulting path shape is actually outset from the original curve, as shown in Figure 4-46.
  7214. Figure 4-46    An outset curve
  7215.  
  7216. The contours created by the GXInsetShape function lie to the right of the original contours if you specify a positive distance and to the left of the original contours if you specify a negative distance. (You can alter this behavior by setting the gxAutoInsetStyle style attribute, as described in Chapter 3, “Geometric Styles,” in this book.)
  7217. For more information about the GXInsetShape function, see page 4-79.
  7218. Determining Whether Two Shapes Touch
  7219.  
  7220. QuickDraw GX provides three functions to help you determine if the areas of two shapes touch—that is, whether they intersect, even at a single point.
  7221. n    The GXTouchesRectanglePoint function determines if a point lies withing the boundaries of a rectangle. 
  7222. n    The GXTouchesBoundsShape function determines if the area covered by a shape touches the area covered an rectangle.
  7223. n    The GXTouchesShape function determines if one shape touches another shape
  7224. The sample function in Listing 4-10 defines a rectangle and a circular path shape.
  7225. Listing 4-10    Creating a rectangle and a circular path shape
  7226.  
  7227. void CreateBoxedCircle(void)
  7228. {
  7229.     gxShape aLargeCircle, aSmallCircle;
  7230.  
  7231.     static gxRectangle largeBounds = {ff(50), ff(50), 
  7232.                                                 ff(150), ff(150)};
  7233.     
  7234.     static long                largeCircleGeometry[] = {1,/* number of contours */
  7235.                                                      4,/* number of points */
  7236.                                                      0xF0000000, 
  7237.                                                      ff(50), ff(50),  /* off */
  7238.                                                      ff(150), ff(50), /* off */
  7239.                                                      ff(150), ff(150),/* off */
  7240.                                                      ff(50), ff(150)};/* off */
  7241.  
  7242.  
  7243.     aLargeCircle = GXNewPaths((gxPaths *) largeCircleGeometry);
  7244.     GXSetShapeFill(aLargeCircle, gxClosedFrameFill);
  7245.  
  7246.     GXDrawRectangle(&largeBounds, gxClosedFrameFill);
  7247.     GXDrawShape(aLargeCircle);
  7248.     GXDisposeShape(aLargeCircle);
  7249. }
  7250. The result of this function is shown in Figure 4-47.
  7251. Figure 4-47    A rectangle containing a circular path
  7252.  
  7253. Given the rectangle and the path shape defined in Listing 4-10, the GXTouchesBoundsShape function:
  7254. GXTouchesBoundsShape(&largeBounds, aLargeCircle)
  7255. returns true; the area of the rectangle does intersect the area of the path. 
  7256. When calculating whether a rectangle and a shape intersect, the GXTouchesBoundsShape function assumes that the rectangle has an even-odd shape fill. For example, if you define another, smaller path shape:
  7257. static long                smallCircleGeometry[] = {1, /* number of contours */
  7258.                                                  4, /* number of points */
  7259.                                                  0xF0000000, 
  7260.                                                  ff(65), ff(65),  /* off */
  7261.                                                  ff(135), ff(65), /* off */
  7262.                                                  ff(135), ff(135),/* off */
  7263.                                                  ff(65), ff(135)};/* off */
  7264. aSmallCircle = GXNewPaths((gxPaths *) smallCircleGeometry);
  7265. GXSetShapeFill(aSmallCircle, gxClosedFrameFill);
  7266. then the call 
  7267. GXTouchesBoundsShape(&largeBounds, aSmallCircle);
  7268. returns true because the smaller path shape intersects the area contained in the rectangle, as shown in Figure 4-48.
  7269. Figure 4-48    A rectangle that touches a circular path shape
  7270.  
  7271. Tthe GXTouchesBoundsShape function returns true even if the rectangle and the path shape share only an edge or even a single point. For example, if you move the small circle to the right by a distance of 85.0 points by calling
  7272. GXMoveShape(aSmallCircle, ff(85), 0);
  7273. as depicted in Figure 4-49, then the following call
  7274. GXTouchesBoundsShape(&largeBounds, aSmallCircle)
  7275. returns true.
  7276. Figure 4-49    A rectangle and a circular path touching at a single point
  7277.  
  7278. The GXTouchesShape function works similarly to the GXTouchesBoundsShape function, but it determines whether any two shapes intersect. 
  7279. As an example, if you give the path shapes defined earlier in this section the even odd shape fill by calling
  7280. GXSetShapeFill(aLargeCircle, gxEvenOddFill);
  7281. GXSetShapeFill(aSmallCircle, gxEvenOddFill);
  7282. then the call
  7283. GXContainsShape(aLargeCircle, aSmallCircle)
  7284. returns true; the small path intersects the area contained in the large path, as shown in Figure 4-50.
  7285. Figure 4-50    A large circular path shape touching a smaller circular path shape
  7286.  
  7287. Implementation Note
  7288. Due to an implementation limit with version 1.0 of QuickDraw GX, the GXTouchesShape function does not allow both of the compared shapes to be framed (that is, have an open-frame or closed-frame shape fill).u
  7289. For information about the GXTouchesRectanglePoint function, see page 4-80.
  7290. For more information about the GXTouchesBoundsShape function, see page 4-81.
  7291. For more information about the GXTouchesShape function, see page 4-82.
  7292. Determining Whether One Shape Contains Another
  7293.  
  7294. QuickDraw GX also provides three functions to help you determine if one area contains another:
  7295. n    The GXContainsRectangle function determines if one rectangle contains another.
  7296. n    The GXContainsBoundsShape function determines if the area contained by a rectangle contains the area covered by a shape.
  7297. n    The GXContainsShape function determines if the area covered by one shape contains the area covered by another shape.
  7298. The sample function in Listing 4-11 creates a small circular path and a larger, donut-shaped path. Examples later in this section compare these shapes to see if one contains the other.
  7299. Listing 4-11    Creating a donut-shaped path and a smaller, concentric path
  7300.  
  7301. void CreateMultiplePaths(void)
  7302. {
  7303.     gxShape twoCircleShape, smallSquareShape;
  7304.  
  7305.     static rectangle smallSquareGeometry[] = {ff(90), ff(90),
  7306.                                                             ff(110), ff(110)};
  7307.  
  7308.  
  7309.     static long     twoCircleGeometry[] = {2, /* # of contours */
  7310.                                                   4, /* # of points */
  7311.                                                   0xF0000000, /* all off */
  7312.                                                   ff(50), ff(50),    
  7313.                                                   ff(150), ff(50), 
  7314.                                                   ff(150), ff(150),  
  7315.                                                   ff(50), ff(150),
  7316.                                                   4, /* # of points */
  7317.                                                   0xF0000000, /* all off */
  7318.                                                   ff(65), ff(65),
  7319.                                                   ff(65), ff(135) ,
  7320.                                                   ff(135), ff(135),
  7321.                                                   ff(135), ff(65)};
  7322.  
  7323.  
  7324.     twoCircleShape = GXNewPaths((gxPaths *) twoCircleGeometry);
  7325.     GXSetShapeFill(twoCircleShape, gxEvenOddFill);
  7326.     
  7327.     smallSquareShape = GXNewRectangle(&smallSquareGeometry);
  7328.     GXSetShapeFill(smallSquareShape, gxEvenOddFill);
  7329.  
  7330.     GXDrawShape(twoCircleShape);
  7331.     GXDisposeShape(twoCircleShape);
  7332.     GXDrawShape(smallSquareShape);
  7333.     GXDisposeShape(smallSquareShape);
  7334. }
  7335. The results of this sample function are shown in Figure 4-51.
  7336. Figure 4-51    A path shape with two contours and a smaller concentric rectangle shape
  7337.  
  7338. Since the GXContainsShape function considers shape fill when calculating whether one shape contains another, the following function call:
  7339. GXContainsShape(twoCircleShape, smallerCircleShape);
  7340. returns false; the area covered by the larger path does not contain the area covered by the smaller path.
  7341. (*** This needs to be tested; it hassn’t always worked like this. What is the expected behavior? ***)
  7342. For more information about the GXContainsShape function, see page 4-86.
  7343. The functions GXContainsRectangle and GXContainsBoundsShape work similarly to the GXContainsShape function, except the input parameters to these functions are rectangle geometries, rather than shapes. The GXContainsRectangle function compares on two rectangle geometries and the GXContainsBoundsShape compares a rectangle geometry to a shape. 
  7344. For more information about the GXContainsRectangle function, see page 4-84.
  7345. For more information about the GXContainsBoundsShape function, see page 4-85.
  7346. Performing Geometric Arithmetic With Shapes
  7347.  
  7348. QuickDraw GX provides six arithmetic operations you can apply to geometric shapes: union, intersection, difference, reverse difference, exclusion, and inversion.
  7349. To illustrate these operations, the sample function in Listing 4-12 creates two intersecting shapes: a diamond-shaped polygon and a circular path.
  7350. Listing 4-12    Creating a diamond-shaped polygon and a circlular path that intersect
  7351.  
  7352. void CreateDiamondAndCircle(void)
  7353. {
  7354.     gxShape  diamondShape, circleShape;
  7355.  
  7356.     static long circleGeometry[] = {1, /* number of contours */
  7357.                                               4, /* number of points */
  7358.                                               0xFF000000, /* control bits */
  7359.                                               ff(100), ff(100),  /* off */
  7360.                                               ff(200), ff(100),  /* off */
  7361.                                               ff(200), ff(200),  /* off */ 
  7362.                                               ff(100), ff(200)}; /* off */
  7363.  
  7364.     static long diamondGeometry[] = {1, /* number of contours */
  7365.                                                4,, /* number of points */
  7366.                                                ff(50), ff(150),
  7367.                                                ff(100), ff(100),
  7368.                                                ff(150), ff(150),
  7369.                                                ff(100), ff(200)};
  7370.  
  7371.     diamondShape = GXNewPolygons((gxPolygons *) diamondGeometry);
  7372.     
  7373.     circleShape = GXNewPaths((gxPaths *) circleGeometry);
  7374.  
  7375.     GXDrawShape(diamondShape);    
  7376.     GXDisposeShape(diamondShape);    
  7377.     GXDrawShape(circleShape);
  7378.     GXDisposeShape(circleShape);
  7379. }
  7380. The resulting shapes are shown in Figure 4-52.
  7381. Figure 4-52    A diamond-shaped polygon geometry and a circular path geometry
  7382.  
  7383. The GXIntersectShape function finds the area common to two shapes. This function takes two parameters—the shapes to intersect—and stores the result in the first parameter.
  7384. If you apply the GXIntersectShape function to the diamond-shaped polygon and the circular path from Listing 4-12 by calling
  7385. GXIntersectShape(diamondShape, circleShape);
  7386. GXDrawShape(diamondShape);
  7387. you get the resulting shape shown in Figure 4-53.
  7388. Figure 4-53    The intersection of a diamond-shaped polygon and a circular path
  7389.  
  7390. Implementation Note
  7391. Due to a implementation limit with QuickDraw GX version 1.0, you can find the intersection of two framed shapes only if the shapes are points, lines, or curves.u
  7392. However, you can find the intersection of a framed shape and a filled shape; the intersection is the part of the framed shape contained in the filled shape. In this case, the target shape must be the framed shape and the operand shape must be the filled shape.
  7393. You can find the intersection of two rectangle geometries—without having to encapsulate those geometries into shapes—using the GXIntersectRectangle function, which is described on page 4-87. Similarly, you can find the union of two rectangle geometries (which is the considered to be the smallest rectangle that contains them both) using the GXUnionRectangle function, which is described on page 4-88.
  7394. The GXUnionShape function combines the areas covered by two shapes. This function also takes two parameters—the shapes to combine—and stores the result in the first parameter.
  7395. If you apply the GXUnionShape function to the diamond-shaped polygon and the circular path from Listing 4-12 by calling
  7396. GXUnionShape(diamondShape, circleShape);
  7397. GXDrawShape(diamondShape);
  7398. you get the resulting shape shown in Figure 4-54.
  7399. Figure 4-54    The union of a diamond-shaped polygon and a circular path
  7400.  
  7401. While you cannot find the union of a framed shape and a filled shape, you can find the union of two framed shapes. If the diamond-shaped polygon and the circular path from Listing 4-12 had closed-frame fills, the resulting union would appear as shown in Figure 4-55.
  7402. Figure 4-55    The union of a framed diamond-shaped polygon and a circular path
  7403.  
  7404. The GXDifferenceShape function subtracts the area of one shape from the area of another. This function takes two parameters—the shape to subtract from and the shape to subtract—and stores the result in the first parameter.
  7405. If you apply the GXDifferenceShape functionto the diamond-shaped polygon and the circular path from Listing 4-12 by calling
  7406. GXDifferenceShape(diamondShape, circleShape);
  7407. GXDrawShape(diamondShape);
  7408. you get the resulting shape shown in Figure 4-56.
  7409. Figure 4-56    The result of subtracting a circular path from a diamond-shaped polygon
  7410.  
  7411. The GXReverseDifferenceShape function is similar to the GXDifferenceShape function, except the GXReverseDifferenceShape function subtracts the first parameter from the second parameter. Like GXDifferenceShape, it also stores the result in the first parameter.
  7412. If you apply the GXReverseDifferenceShape function to the diamond-shaped polygon and the circular path from Listing 4-12 by calling
  7413. GXReverseDifferenceShape(diamondShape, circleShape);
  7414. GXDrawShape(diamondShape);
  7415. you get the resulting shape shown in Figure 4-57. 
  7416. Figure 4-57    The result of subtracting a diamond-shaped polygon from a circular path
  7417.  
  7418. The GXExcludeShape function performs the exclusive-or operation on the areas of two shapes—that is, it finds the area that is covered by one shape or the other, but not by both shapes.
  7419. If you apply the GXExcludeShape function to the diamond-shaped polygon and the circular path from Listing 4-12 by calling
  7420. GXExcludeShape(diamondShape, circleShape);
  7421. GXDrawShape(diamondShape);
  7422. you get the resulting shape shown in Figure 4-58. 
  7423. Figure 4-58    The result of the exclusive-or operation on a polygon and a path
  7424.  
  7425. Finally, QuickDraw GX provides the GXInvertShape function which inverts the area covered by a shape—that is, the resulting shape covers all of the area not covered by the origingal shape. This function takes one parameter—the shape to invert—and stores the result in this parameter.
  7426. If you apply the GXInvertShape function to the diamond-shaped polygon from Listing 4-12 by calling
  7427. GXInvertShape(diamondShape);
  7428. you get the resulting shape shown in Figure 4-57. Notice that this shape extends to the full extent its view port.
  7429. Figure 4-59    An inverted diamond 
  7430.  
  7431. For more information about these arithmetic operations, see the function descriptions in “Performing Geometric Arithmetic with Shapes” beginning on page 4-87.
  7432.  
  7433.  
  7434. Geometric Operations Reference
  7435.  
  7436. QuickDraw GX provides many functions that allow you to perform geometric manipulations on shapes. This section describes the data types and functions that are related to these operations.
  7437. Constants and Data Types
  7438.  
  7439. This section describes the enumeration QuickDraw GX uses to specify information about contour direction.
  7440. Contour Directions
  7441.  
  7442. QuickDraw GX assigns a contour direction to every contour in a shape: contours are either clockwise or counterclockwise. QuickDraw GX uses the contour direction primarily when filling a shape.
  7443. Contour directions are specified by the gxContourDirections enumeration, which is defined as follows:
  7444. enum gxContourDirections {
  7445.     gxCounterclockwiseDirection,
  7446.     gxClockwiseDirection
  7447. };
  7448. typedef long gxContourDirection;
  7449. Constant descriptions
  7450. gxCounterclockwiseDirection
  7451. A counterclockwise contour direction.
  7452. gxClockwiseDirection
  7453. A clockwise contour direction. 
  7454. For more information about contours, see Chapter 2, “Geometric Shapes,” in this book.
  7455. For more information about contour direction, see “Contours and Contour Direction” beginning on page 4-4. 
  7456. Functions
  7457.  
  7458. QuickDraw GX provides functions you can call to perform geometric operations on geometric shapes and their geometries. This section includes descriptions of the functions that allow you to
  7459. n    determine and alter the contour direction of a shape’s contours
  7460. n    reduce and simplify a shape’s geometry
  7461. n    incorporate style information into a shape’s geometry
  7462. n    obtain geometric information about a shape’s geometry
  7463. n    determine and alter the bounding rectangle of a shape
  7464. n    inset a shape
  7465. n    perform geometric arithmetic on shapes
  7466. Determining and Reversing Contour Direction
  7467.  
  7468. The contours of geometric shapes have a contour direction: clockwise or contourclockwise. QuickDraw GX determines the contour direction of a contour given
  7469. n    the order and position of the geoemtric points that make up the contour
  7470. n    the contour’s relative position to other contours in the shape, if the shape has multiple contours
  7471. For a discussion of geometric points, see Chapter 2, “Geometric Shapes,” in this book.
  7472. The GXGetShapeDirection function allows you to determine the contour direction of a specified contour of a shape.
  7473. The GXReverseShape function allows you to reverse the order of the geometric points that define a contour and therefore reverse the contour’s direction.
  7474. GXGetShapeDirection  
  7475.  
  7476. You can use the GXGetShapeDirection function to determine whether a contour has a clockwise or counterclockwise direction.
  7477. gxContourDirection GXGetShapeDirection(gxShape source, 
  7478.                                                     long contour);
  7479. source    A reference to the shape containing the contour.
  7480. contour    The index of the contour whose direction you want to determine.
  7481. function result    The direction of the contour, either gxClockwiseDirection or counterclockwiseDirection.
  7482. DESCRIPTION
  7483. The GXGetShapeDirection function indicates whether QuickDraw GX considers the contour indicated by the contour parameter of the shape indicated by the source parameter to be clockwise or contourclockwise. You can use this information to determine how QuickDraw GX will draw a shape that has the inside-frame style or outside-frame style attribute set, or how the GXInsetShape function will affect a shape.
  7484. For empty and full shapes, this function returns the result code graphics_type_does_not_have_multiple_contours .
  7485. For point shapes and line shapes, this function always returns gxClockwiseDirection. Although the order of the geometric points in a line shape’s geometry does not affect the result of this function, they may affect how QuickDraw GX draws the line. For example, if the line is dashed, the order of the geometric points determines the end of the line at which dashing begins. Also, if the line has a pen width and the inside-frame style or outside-frame style attribute is set, the order of the geometric points determines the side of the geometry on which QuickDraw GX draws the line.
  7486. For rectangle shapes, the result of this function is determined by examining which corners are specified by the geometric points. For a rectangle whose geometry includes the upper-left point and the lower-right point, this function returns gxClockwiseDirection, regardless of the order of the two points in the geometry. For a rectangle whose geometry includes the upper-right point and the lower-left point, this function returns gxCounterclockwiseDirection, again regardless of the order of the two points.
  7487. For curve shapes, polygon shapes, and path shapes, reversing the order of any contour’s geometric points reverses the result of this function. Notice that although line shapes always have clockwise direction, a line contour of a polygon or path shape can have either clockwise or counterclockwise direction.
  7488. ERRORS, WARNINGS, AND NOTICES
  7489. Errors    
  7490. out_of_memory    
  7491. shape_is_nil    
  7492. contour_is_less_than_zero    
  7493. Warnings    
  7494. graphics_type_does_not_have_multiple_contours    
  7495. contour_out_of_range    
  7496.  
  7497. SEE ALSO
  7498. For examples of this function, see “Determining and Reversing Contour Direction” beginning on page 4-21.
  7499. To reverse the order of geoemtric points in a shape’s geometry, use the GXReverseShape function, described in the next section.
  7500. For a description of the GXInsetShape function, see page 4-79. For a description of the gxInsideFrameStyle and gxOutsideFrameStyle style attributes, see the Chapter 3, “Geometric Styles,” in this book.
  7501. GXReverseShape  
  7502.  
  7503. You can use the GXReverseShape function to reverse the order of the geometric points in a shape’s contour.
  7504. void GXReverseShape(gxShape target, long contour);
  7505. target    A reference to the shape containing the contour.
  7506. contour    The number of the contour you want to reverse. You may specify a value of 0 for this parameter to indicate all contours.
  7507. DESCRIPTION
  7508. The GXReverseShape function reverses the order of the geometric points of the contour specified by the contour parameter in the shape specified by the target parameter.
  7509. If you specify a value of 0 for the contour parameter, this function reverses the order of the geometric points in each contour of the target shape, but does not affect the order of the contours themselves.
  7510. You can use this function to control how QuickDraw GX
  7511. n    draws shapes with a winding shape fill
  7512. n    draws shapes with the inside-frame style or outside-frame style attributes set
  7513. n    places dashes on a dashed contour
  7514. n    insets shapes
  7515. ERRORS, WARNINGS, AND NOTICES
  7516. Errors    
  7517. out_of_memory    
  7518. shape_is_nil    
  7519. contour_is_less_than_zero    
  7520. Warnings    
  7521. contour_out_of_range    
  7522. shape_access_not_allowed    
  7523.  
  7524. SEE ALSO
  7525. For examples of this function, see “Determining and Reversing Contour Direction” beginning on page 4-21.
  7526. To determine the direction of a contour, use the GXGetShapeDirection function, described on page 4-61.
  7527. For a discussion of geometric points, see the Chapter 2, “Geometric Shapes.”
  7528. For a discussion of contour direction, see “Contours and Contour Direction” beginning on page 4-4. 
  7529. For a discussion of dashes and the inside-frame style and outside-frame style attributes, see the Chapter 3, “Geometric Styles,” in this book.
  7530. For a description of the GXInsetShape function, see page 4-79. 
  7531. Breaking Shape Contours
  7532.  
  7533. Each contour of a polygon or path shape can be made up of many contours: each polygon contour can contain many line,s and each path contour can contain many lines and curves.
  7534. The GXBreakShape function allows you to specify a geometric point at which to break a single contour into two contours.
  7535. GXBreakShape  
  7536.  
  7537. You can use the GXBreakShape function to break a single contour into two contours.
  7538. void GXBreakShape(gxShape target, long index);
  7539. target    A reference to the shape containing the contour to break.
  7540. index    The geometric index of the point at which to break the contour.
  7541. DESCRIPTION
  7542. The GXBreakShape function breaks an existing contour into two contours at a specified geometric point.
  7543. For empty, full, point, bitmap, and picture shapes, this function posts the warning graphic_type_does_not_contain_points. For rectangle shapes, this function posts a rectangles_cannot_be_inserted_into notice.
  7544. This function can convert the shape type of the target shape. For example, you can break line shapes at their first point by specifying a geometric index of 1 for the index parameter. The result is a polygon shape with two contours: the first contour is empty and the second contour is the original line. If you specifya value of 2 for the index parameter, this function posts the notice gxShape_already_broken, and the original line is unaffected.
  7545. Similarly, you can break curve shapes at their first point; the result is a path shape with two contours. You can also break curve shapes at the off-curve control point by specifying a value of 2 for the index parameter. The resulting path shape has two contours: the first contour ends at the off-curve control point, and the second contour begins at the off-curve control point. You must add on-curve geometric points at the end of the first contour and the beginning of the second contour before drawing this path shape.
  7546. For polygons and paths:
  7547. n    If the geometric index you specify corresponds to the first point of a contour, this function inserts an empty contour into the shape before the specified point.
  7548. n    If the geometric index you specify corresponds to the last point of a contour, this function posts a gxShape_already_broken notice, and the original shape is unaffected.
  7549. n    If the geometric index you specify corresponds to a point between the first and last points of a contour, this function breaks the existing contour into two contours. The specified point becomes the first point of the new second contour.
  7550. ERRORS, WARNINGS, AND NOTICES
  7551. Errors    
  7552. out_of_memory    
  7553. shape_is_nil    
  7554. index_is_less_than_one    
  7555. Warnings    
  7556. shape_access_not_allowed    
  7557. graphic_type_does_not_contain_points    
  7558. index_out_of_range    
  7559. contour_out_of_range    
  7560. Notices (debugging version)    
  7561. gxShape_already_broken    
  7562.  
  7563. SEE ALSO
  7564. For an example of this function, see “Breaking Shape Contours” beginning on page 4-25.
  7565. For a discussion of geometric points, see Chapter 2, “Geometric Shapes,” in this book. For other methods of breaking contours, see the shape-editing functions also described in that chapter.
  7566. To learn how this function works for the typographic shapes, see Inisde Macintosh: QuickDraw GX Typography.
  7567. Reducing and Simplifying Shapes
  7568.  
  7569. The geometries of QuickDraw GX shapes can contain many unnecessary or complicating elements:
  7570. n    duplicate geometric points
  7571. n    unnecessary colinear geometric points
  7572. n    crossed contours
  7573. n    overlapping contours
  7574. n    unnecessary contour breaks
  7575. n    a more complex shape type than necessary
  7576. The GXReduceShape function eliminates unnecessary geometric points.
  7577. The GXSimplifyShape function eliminates unnecessary geometric points, crossed contours, overlapping contours, unnecessary contour breaks, and also sets a shape’s shape type to the simplest type necessary to describe the shape’s geometry.
  7578. GXReduceShape  
  7579.  
  7580. You can use the GXReduceShape function to remove unnecessary geometric points from a shape’s contour.
  7581. void GXReduceShape(gxShape target, long contour);
  7582. target    A reference to the polygon or path shape containing the contour whose unnecessary geometric points you want to eliminate.
  7583. contour    The index of the contour you want to reduce. You may specify a value of 0 for this parameter to indicate all contours.
  7584. DESCRIPTION
  7585. The GXReduceShape function removes unnecessary geometric points from the contour indicated by the contour parameter of the shape indicated by the target parameter. The geometric points removed by this function include both duplicate and colinear geometric points. Duplicate geometric points are sequential geometric points in the same contour with the same x and y coordinates. Colinear geometric points are sequential geometric points that fall on the same line as the preceding and the subsequent geometric point. Although this function may affect the geometry of a shape, the resulting shape appears the same as the original shape when drawn.
  7586. Note
  7587. Under certain circumstances, the GXReduceShape function actually increases the number of geometric points used to define a shape. For path shapes, the number of geometric points in the resulting shape can be up to 4/3 the number of points in the original shape. Even in this case, the resulting shape appears the same as the original shape when drawn.u
  7588. The GXReduceShape function does consider the curve error of the target shape when selecting which geometric points to remove. If the distance between a point and a neighboring point is less than that indicated by the curve error, the GXReduceShape function considers them to be duplicate points. If you specify a target shape with a nonzero curve error, the resulting shape may draw differently than the original shape—the greater the curve error, the more drastic the difference may be. For shapes with many points within a distance of less than that indicated by the curve error, the resulting shape can sometimes degenerate to a surprising result.
  7589. The shape fill of the target shape can also affect the results of this function. For example, if the first point and the last point of a contour are the same geoemtric point, this function removes the last point if the target shape has a closed-frame fill or any of the solid fills. However, if the target shape has an open-frame fill, this function does not remove the last point.
  7590. Similarly, if one or more of the final points of a contour is colinear with one or more of the initial points of that contour, this function considers them all to lie on the same line if the target shape has a closed-frame fill or any of the solid fills and the unnecessary points are removed—even the first and last point of the original contour can be removed. However, if the target shape has an open-frame fill, the first and the last points of a contour are never removed.
  7591. This function only operates within individual contours; it never combines contours or compares points from different contours. Also, this function does not convert between shape types. The resulting shape always has the same shape type as the original shape.
  7592. ERRORS, WARNINGS, AND NOTICESErrors    
  7593. out_of_memory    
  7594. shape_is_nil    
  7595. Warnings    
  7596. graphic_type_cannot_be_reduced    
  7597. contour_out_of_range    
  7598. shape_access_not_allowed    
  7599.  
  7600. SEE ALSO
  7601. For examples of this function, see “Eliminating Unnecessary Geometric Points” beginning on page 4-27.
  7602. For more information about reduced and simplified shapes, see “Reducing and Simplifying Shape Geometries” beginning on page 4-8.
  7603. For a discussion of geometric points and contours, see Chapter 2, “Geometric Shapes,” in this book.
  7604. To learn how this function works for the typographic shapes, see Inisde Macintosh: QuickDraw GX Typography.
  7605. GXSimplifyShape  
  7606.  
  7607. You can use the GXSimplifyShape function to eliminate froma a shape any unnecessary contour breaks, contour crossings, and internal contour loops.
  7608. void GXSimplifyShape(gxShape target);
  7609. target    A reference to the shape you want to simplify.
  7610. DESCRIPTION
  7611. The GXSimplifyShape function performs operations on the geometry of the shape specified by the target parameter and simplifies the description of the shape, sometimes changing the shape type, without affecting how the shape is drawn.
  7612. Most importantly, the resulting shape has no crossed contours. The GXSimplifyShape function adds geometric points and changes contour directions to redefine the shape’s geometry so that no contour crosses over itself or any other contour.
  7613. This function also removes unnecessary contour breaks. If the last point of one contour is identical to the first point of the next contour, this function combines the two contours into a single contour. 
  7614. Note
  7615. Under certain circumstances, the GXSimplifyShape function actually increases the number of geometric points and the number of contours used to defined a shape. However, the simplified shape still appears the same as the original shape when drawn.u
  7616. If the geometry of the original shape can be expressed as a geometry of a simpler shape type, this function converts the shape to the simpler type. For example, if the shape referenced by the target parameter is a polygon, but the geometry of that polygon defines a simple square, the GXSimplifyShape function converts the shape to a rectangle type and redefines the geometry as appropriate. As another example, a path shape with no curved contours is converted to a polygon shape type.
  7617. The shape fill of the target shape also affects the simplifications. For example, if the target shape has two circular, concentric contours (an inner contour and an outer contour) and both contours have the same contour direction, the following occurs:
  7618. n    If the shape has a winding shape fill, the inner contour does not affect how the shape is drawn. In this case, the GXSimplifyShape function removes the inner contour.
  7619. n    If the shape has an even-odd shape fill, the inner contour does affect how the shape is drawn. In this case, the GXSimplifyShape function maintains the inner contour, but it reverses the direction of that contour. 
  7620. As a result of these simplifications, changing the shape fill of a simplified shape from winding fill to even-odd fill or from even-odd fill to winding fill does not affect the appearance of the shape when drawn.
  7621. ERRORS, WARNINGS, AND NOTICESErrors    
  7622. out_of_memory    
  7623. shape_is_nil    
  7624. functionality_unimplemented (for picture shapes)    
  7625. Warnings    
  7626. number_of_contours_exceeds_implementation_limit    
  7627. number_of_points_exceeds_implementation_limit    
  7628. size_of_path_exceeds_implementation_limit    
  7629. size_of_polygon_exceeds_implementation_limit    
  7630. shape_access_not_allowed    
  7631. unable_to_traverse_open_contour_that_starts_or_ends_off_the_curve    
  7632. Notices (debugging version)    
  7633. shape_already_in_simple_form    
  7634.  
  7635. SEE ALSO
  7636. For examples of this function, see “Simplifying Shapes” beginning on page 4-29.
  7637. For more information about simplified shapes, see “Reducing and Simplifying Shape Geometries” beginning on page 4-8.
  7638. For a discussion of geometric points and contours, see Chapter 2, “Geometric Shapes,” in this book. 
  7639. To remove unnecessary geometric points but not perform other simplifications, use the GXReduceShape function, described on page 4-66.
  7640. To learn how this function works for the typographic shapes, see Inisde Macintosh: QuickDraw GX Typography.
  7641. Incorporating Style Information Into Shape Geometries
  7642.  
  7643. QuickDraw GX requires that shapes used for certain purposes (caps, joins, dashes, patterns, and clips) be in primitive form—that is, their style modifications must be incorporated into their geometries. For example, the GXSetShapeDash function requires that the shape used for dashing be in primitive form; the GXSetShapeCap, GXSetShapeJoin, and GXSetShapePattern functions are similar. 
  7644. For more information about the primitive form of shapes and for examples of functions that use shapes in their primitive form, see Chapter 3, “Geometric Styles,” in this book.
  7645. The GXPrimitiveShape function converts a shape to its primitive form, incorporating the modifications made by the shape’s style into shape’s geometry.
  7646. GXPrimitiveShape  
  7647.  
  7648. You can use the GXPrimitiveShape function to convert a shape to its primitive form.
  7649. void GXPrimitiveShape(gxShape target);
  7650. target    A reference to the shape to convert to primitive form.
  7651. DESCRIPTION
  7652. The GXPrimitiveShape function converts the shape referenced by the target parameter to its primitive form—that is, it changes the geometry, shape fill, and shape type of the target shape to incorporate the information from the original shape’s style. 
  7653. For example, a horizontal line shape with a greater-than-zero pen width becomes a filled rectangle shape. A diagonal line shape with a greater-than-zero pen width becomes a filled polygon shape. A curve shape with a greater-than-zero pen width becomes a filled path shape.
  7654. This function incorporates all the elements of the target shape’s style (including pen width, dashes, joins, and so on) into the target shape’s geometry, shape fill, and shape type. For example, a framed shape dashed with rectangles becomes a polygon shape with multiple contours—each contour representing one of the original dashes.
  7655. For the geometric shapes, the shape resulting from this function can be a hairline shape or a solid-filled shape. In either case, the information from the style object is no longer necessary because it has been incorporated into the shape object itself.
  7656. Implementation Note
  7657. In version 1.0 of QuickDraw GX, this function posts an error of functionality_unimplemented for picture shapes.u
  7658. The result of the GXPrimitiveShape function is not simplified, nor are its unnecessary geometric points removed. You may want to simplify or reduce the resulting shape by calling the GXSimplifyShape function or the GXReduceShape function.
  7659. ERRORS, WARNINGS, AND NOTICESErrors    
  7660. out_of_memory    
  7661. shape_is_nil    
  7662. functionality_unimplemented    
  7663. Warnings    
  7664. shape_already_in_primitive_form    
  7665. shape_access_not_allowed    
  7666. unable_to_traverse_open_contour_that_starts_or_ends_off_the_curve    
  7667. face_override_style_font_must_match_style    
  7668.  
  7669. SEE ALSO
  7670. For examples of this function, see “Converting a Shape to Primitive Form” beginning on page 4-34.
  7671. For more information about the primitive form of shapes and for examples of functions that use shapes in their primitive form, see Chapter 3, “Geometric Styles,” in this book.
  7672. To eliminate unnecessary geometric points, use the GXReduceShape function, described on page 4-66. To simplify a shape’s contours, use the GXSimplifyShape function, described on page 4-67.
  7673. To learn how this function works for the typographic shapes, see Inisde Macintosh: QuickDraw GX Typography.
  7674. Finding Geometric Information About Shapes
  7675.  
  7676. The functions described in this section calculate geometric information about a shape.
  7677. The GXGetShapeLength function calculates the length of a particular contour or all contours in a shape.
  7678. The GXShapeLengthToPoint function determines the point that falls at a specifed distance along a particular contour or all combined contours of a shape.
  7679. The GXGetShapeCenter function determines the center point of a particular contour or all combined contours of a shape’s geometry.
  7680. The GXGetShapeArea function calculates the area covered by a particular contour or all combined contours of a shape’s geometry.
  7681. You can also use the GXGetShapeBounds function, described in “Getting and Setting Shape Bounds” beginning on page 4-76, to find geometric information about a shape—in this case, the shape’s bounding rectangle.
  7682. GXGetShapeLength   
  7683.  
  7684. You can use the GXGetShapeLength function to determine the length of a particular contour or all contours of a shape.
  7685. gxWide *GXGetShapeLength(gxShape source, long index, 
  7686.                                  gxWide *length);
  7687. source    A reference to the shape containing the contour.
  7688. index    The index of the contour you want to measure. You may specify a value of 0 for this parameter to measure all contours.
  7689. function result    The length of the indicated contour.
  7690. DESCRIPTION
  7691. The GXGetShapeLength function returns as the function result the length of the perimeter of a particular contour of a shape. This function calculates the length of the contour as defined in the shape’s geometry; it does not consider transformations to the shape made by the shape’s transform.
  7692. ERRORS, WARNINGS, AND NOTICESErrors    
  7693. out_of_memory    
  7694. shape_is_nil    
  7695. parameter_is_nil    
  7696. contour_is_less_than_zero    
  7697. Warnings    
  7698. contour_out_of_range    
  7699. shape_does_not_have_length    
  7700. unable_to_traverse_open_contour_that_starts_or_ends_off_the_curve    
  7701.  
  7702. SEE ALSO
  7703. For an example of this function, see “Finding Geometric Information About a Shape” beginning on page 4-36.
  7704. For a discussion of contours, see Chapter 2, “Geometric Shapes,” in this book.
  7705. To learn how this function works for the typographic shapes, see Inside Macintosh: QuickDraw GX Typography.
  7706. GXShapeLengthToPoint  
  7707.  
  7708. You can use the GXShapeLengthToPoint function to determine the point that falls at a certain distance along a contour of a shape.
  7709. gxPoint *GXShapeLengthToPoint(gxShape target, long index, 
  7710.                                           fixed length, gxPoint *location, 
  7711.                                           gxPoint *tangent);
  7712. target    A reference to the shape containing the contour you want to examine.
  7713. index    The number of the contour within the shape. You may specify a value of 0 for this parameter to indicate that the function should start measuring at the beginning of the first contour and continue through all contours.
  7714. length    The distance along the contour.
  7715. location    The point that lies along the contour at that distance.
  7716. tangent    A tangent vector representing the slope of the contour at that distance.
  7717. function result    The point that lies along the contour at the specified distance. (This value is the same as the value returned in the location parameter.)
  7718. DESCRIPTION
  7719. The GXShapeLengthToPoint function returns the location of the point that lies at the distance specified by the length parameter along the contour specified by the index parameter of the target shape. 
  7720. If you provide a pointer for the tangent parameter that is not nil, this function returns the slope of the specified contour at that point, in the form of a tangent vector. (The tangent vector implicitly starts at point (0.0, 0.0) and ends at the point indicated by the returned tangent parameter.) 
  7721. This function measures the contour length as defined in the shape’s geometry; it does not consider transformations to the shape made by the shape’s transform.
  7722. ERRORS, WARNINGS, AND NOTICESErrors    
  7723. out_of_memory    
  7724. shape_is_nil    
  7725. length_is_less_than_zero    
  7726. Warnings    
  7727. shape_does_not_have_length    
  7728. contour_out_of_range    
  7729. length_out_of_range    
  7730. unable_to_traverse_open_contour_that_starts_or_ends_off_the_curve    
  7731.  
  7732. SEE ALSO
  7733. For an example of this function, see “Finding Geometric Information About a Shape” beginning on page 4-36.
  7734. For a discussion of contours, see Chapter 2, “Geometric Shapes,” in this book.
  7735. To measure the length of a contour, use the GXGetShapeLength function, described on page 4-71.
  7736. To learn how this function works for the typographic shape types, see Inisde Macintosh: QuickDraw GX Typography.
  7737. GXGetShapeCenter  
  7738.  
  7739. You can use the GXGetShapeCenter function to determine the center of a specified contour of a shape.
  7740. gxPoint *GXGetShapeCenter(gxShape source, long index, 
  7741.                                   gxPoint *center);
  7742. source    A reference to the shape containing the contour whose center you want to find.
  7743. index    The number of the contour whose center you want to find. You may specify a value of 0 to indicate you want to find the center of the entire shape.
  7744. center    The point that falls at the center of the specified contour.
  7745. function result    The point that falls at the center of the specified contour. (This value is the same as the value returned in the center parameter.)
  7746. DESCRIPTION
  7747. The GXGetShapeCenter function determines the point that falls at the center of the contour specified by the index parameter of the shape specified by the source parameter. If you specify a value of 0 for the index parameter, this function finds the center point of the entire source shape.
  7748. The center point of a shape is not merely the center of the shape’s bounding rectangle; rather it is the “center of gravity” of a shape. The center point is defined to be the point such that half of a shape’s area lies above the point and half of the shapes area lies below the point. Similarly, half of the shape’s area lies to the left of the point and half of the shapes area lies to the right of the point.
  7749. This function finds the center of a shape (or of a particular contour) as defined by the source shape’s geometry; it does not consider shape fill or transformations to the shape made by the shape’s transform.
  7750. ERRORS, WARNINGS, AND NOTICESErrors    
  7751. out_of_memory    
  7752.  
  7753. SEE ALSO
  7754. For examples of this function, see “Finding Geometric Information About a Shape” beginning on page 4-36.
  7755. To find the bounding rectangle of a shape or a contour of a shape, use the GXGetShapeBounds function described on page 4-76.
  7756. To learn how this function works for the typographic shapes, see Inisde Macintosh: QuickDraw GX Typography.
  7757. GXGetShapeArea  
  7758.  
  7759. You can use the GXGetShapeArea function to determine the area covered by a specific contour of a shape’s geometry.
  7760. gxWide *GXGetShapeArea(gxShape source, long index, gxWide *area);
  7761. source    A reference to the shape containing the contour whose area you want to determine.
  7762. index    The number of the contour whose area you want to determine. You may specify a value of 0 for this parameter to indicate you want to determine the area of the entire shape.
  7763. area    The area covered by the contour.
  7764. function result    The area covered by the contour. (This value is the same as the value returned in the area parameter.)
  7765. DESCRIPTION
  7766. The GXGetShapeArea function returns the area covered by the contour indicated by the index parameter of the shape indicated by the source parameter. This function considers only the geometry of the source shape—it does not consider the shape fill of the shape. The same geometry returns the same area whether the shape has one of the framed fills, an even-odd fill, a winding fill, or one of the inverse fills.
  7767. Some shapes have overlapping contours with the same contour direction. (When drawing these shapes, QuickDraw GX fills these areas if the shape has a winding fill and does not fill these areas if the shape has an even-odd fill.) The GXGetShapeArea function counts these overlapping areas twice. To correct this calculation, call the GXSimplifyShape function before calling the GXGetShapeArea function:
  7768. n    For shapes with a winding shape fill, the GXSimplifyShape function eliminates the inner contour and, therefore, the GXGetShapeArea function counts the overlapping area only once.
  7769. n    For shapes with an even-odd shape fill, the GXSimplifyShape function reverses the contour direction of the internal contour , and therefore the GXGetShapeArea function does not count the overlapping area at all. 
  7770. This function measures the shape area as defined in the shape’s geometry; it does not consider transformations to the shape made by the shape’s transform.
  7771. ERRORS, WARNINGS, AND NOTICESErrors    
  7772. out_of_memory    
  7773. shape_is_nil    
  7774. parameter_is_nil    
  7775. Warnings    
  7776. shape_does_not_have_area    
  7777. contour_out_of_range    
  7778.  
  7779. SEE ALSO
  7780. For examples of this function, see “Finding Geometric Information About a Shape” beginning on page 4-36.
  7781. For a discussion of shape fills, see Chapter 2, “Geometric Shapes,” in this book
  7782. To simplify a shape before measuring its area, use the GXSimplifyShape function, described on page 4-67.
  7783. To learn how this function works for the typographic shapes, see Inisde Macintosh: QuickDraw GX Typography.
  7784. Getting and Setting Shape Bounds
  7785.  
  7786. Every shape has a bounding rectangle—the smallest rectangle that contains the shape. The functions in this section allow you to determine and alter a shape’s bounding rectangle.
  7787. The GXGetShapeBounds function finds the bounding rectangle of a shape, or of a specified contour of a shape.
  7788. The GXSetShapeBounds function allows you to alter a shape’s bounding rectangle (and thereby move and resize the shape).
  7789. GXGetShapeBounds  
  7790.  
  7791. You can use the GXGetShapeBounds function to determine the bounding rectangle of a shape or of a specified contour of a shape.
  7792. gxRectangle *GXGetShapeBounds(gxShape source, long index, 
  7793.                                       gxRectangle *bounds);
  7794. source    A reference to the shape containing the contour whose bounding rectangle you want to find.
  7795. index    The number of the contour whose bounding rectangle you want to find. You may specify a value of 0 to indicate you want to find the bounding rectangle of the entire shape.
  7796. bounds    The bounding rectangle of the specified contour.
  7797. function result    The bounding rectangle of the specified contour. (This value is the same as the value returned in the bounds parameter.)
  7798. DESCRIPTION
  7799. The GXGetShapeBounds function determines the bounding rectangle of the contour specified by the index parameter of the shape specified by the source parameter. If you specify a value of 0 for the index parameter, this function finds the bounding rectangle of the entire source shape.
  7800. The bounding rectangle of a shape (or of a contour of a shape) is the smallest rectangle that contains the geometry of the shape (or of the contour).
  7801. This function finds the bounding rectangle of the source shape (or a contour of the source shape) as defined by the source shape’s geometry; it does not consider shape fill or transformations to the shape made by the shape’s transform.
  7802. ERRORS, WARNINGS, AND NOTICESErrors    
  7803. out_of_memory    
  7804. shape_is_nil    
  7805. contour_is_nil    
  7806. contour_is_less_than_zero    
  7807. illegal_type_for_shape    
  7808. Warnings    
  7809. graphic_type_does_not_contain_points    
  7810. contour_out_of_range    
  7811.  
  7812. SEE ALSO
  7813. For examples of this function, see “Finding Geometric Information About a Shape” beginning on page 4-36.
  7814. For a discussion of rectangles and bounding rectangles, see Chapter 2, “Geometric Shapes,” in this book.
  7815. To find the center of a shape or a contour of a shape, use the GXGetShapeCenter function, which is described on page 4-73.
  7816. To change the bounding rectangle of a shape, use the GXSetShapeBounds function, described in the next section.
  7817. To learn how this function works for the typographic shapes, see Inisde Macintosh: QuickDraw GX Typography.
  7818. GXSetShapeBounds  
  7819.  
  7820. You can use the GXSetShapeBounds function to change a shape’s bounding rectangle, thereby moving and resizing the shape.
  7821. void GXSetShapeBounds(gxShape target, 
  7822.                              const gxRectangle *newBounds);
  7823. source    A reference to the shape whose bounding rectangle you want to change.
  7824. newBounds    The new bounding rectangle.
  7825. DESCRIPTION
  7826. The GXSetShapeBounds function changes the bounding rectangle of the shape specified by the source parameter to be the rectangle specified by the newBounds parameter.
  7827. How this function changes the bounding rectangle is determined by the source shape’s gxMapTransformShape shape attribute:
  7828. n    If the gxMapTransformShape shape attribute is not set, the function changes the geometry of the source shape to fit the new bounding rectangle
  7829. n    If the gxMapTransformShape shape attribute is set, the function does not alter the shape’s geometry directly; instead, it changes the mapping of the shape’s transform object to scale the shape to fit in the new bounding rectangle.
  7830. By changing a shape’s bounding rectangle, you can move the shape as well as scale it in the horizontal and vertical dimensions.
  7831. ERRORS, WARNINGS, AND NOTICESErrors    
  7832. out_of_memory    
  7833. shape_is_nil    
  7834. parameter_is_nil    
  7835. Warnings    
  7836. scale_shape_out_of_range    
  7837. shape_access_not_allowed    
  7838. unable_to_traverse_open_contour_that_starts_or_ends_off_the_curve    
  7839. shape_passed_has_no_bounds    
  7840. character_substitution_took_place    
  7841. font_substitution_took_place    
  7842.  
  7843. SEE ALSO
  7844. For examples of this function, see “Setting a Shape’s Bounding Rectangle” beginning on page 4-42.
  7845. For a discussion of rectangles and bounding rectangles, see Chapter 2, “Geometric Shapes,” in this book.
  7846. For a discussion of the gxMapTransformShape shape attribute, see the chapters “Shape Objects” and “Transform Objects” in Inside Macintosh: QuickDraw GX Objects.
  7847. To determine the bounding rectangle of a shape, use the GXGetShapeBounds function, described on page 4-76.
  7848. To learn how this function works for the typographic shapes, see Inside Macintosh: QuickDraw GX Typography.
  7849. Insetting Shapes
  7850.  
  7851. The GXInsetShape function, described in this section, provides a way to inset or outset the contours of a shape a specified distance from the original contours.
  7852. GXInsetShape  
  7853.  
  7854. You can use the GXInsetShape procedure to inset a shape’s geometry.
  7855. void GXInsetShape(gxShape target, fixed inset);
  7856. source    A reference to the shape whose geometry you want to inset.
  7857. inset    The distance to inset the geometry of the shape.
  7858. DESCRIPTION
  7859. The GXInsetShape function insets the geometry of the shape specified by the target parameter by the distance specified in the inset parameter. The on-curve geometric points of the resulting geometry are the specified distance inside the contour of the original geometry.
  7860. QuickDraw GX uses the direction of a contour to define which side is the inside of a contour: the inside is the side to right of the contour. As a result, insetting clockwise contours makes them smaller while insetting counterclockwise contours makes them larger.
  7861. You can override this behavior by setting the gxAutoInsetStyle style attribute. If you set this style attribute for a shape, QuickDraw GX finds the true inside of the contour, regardless of its contour direction. With this attribute set, insetting a contour makes it smaller, whether it has a clockwise direction or a counterclockwise direction. 
  7862. You can specify a positive or negative value for the inset parameter: positive values move the geometry to the inside of the original geometry; negative values move it outside the original geometry.
  7863. ERRORS, WARNINGS, AND NOTICESErrors    
  7864. out_of_memory    
  7865. shape_is_nil    
  7866. Warnings    
  7867. shape_access_not_allowed    
  7868.  
  7869. SEE ALSO
  7870. For examples of this function, see “Insetting Shapes” beginning on page 4-45.
  7871. For a discussion of contours and contour direction, see Chapter 2, “Geometric Shapes,” in this book.
  7872. For a discussion of the gxAutoInsetStyle style attribute, see Chapter 3, “Geometric Styles,” in this book.
  7873. To change the bounding rectangle of a shape, use the GXSetShapeBounds function, described on page 4-77.
  7874. To learn how this function works for the typographic shapes, see Inisde Macintosh: QuickDraw GX Typography.
  7875. Determining Whether Two Areas Intersect
  7876.  
  7877. The GXIntersectShape function, described on page 4-89, determines if two shapes intersect and, if so, what their intersection is.
  7878. The functions described in this section simply determine if two areas intersect.
  7879. The GXTouchesRectanglePoint function determines whether the area covered by a rectangle intersects a point.
  7880. The GXTouchesBoundsShape function determines whether the area covered by a rectangle intersects a shape.
  7881. The GXTouchesShape function determines whether the area covered by one shape intersects the area covered by another.
  7882. GXTouchesRectanglePoint  
  7883.  
  7884. You can use the GXTouchesRectanglePoint function to determine if a point lies within or on the edge of a rectangle.
  7885. gxBoolean GXTouchesRectanglePoint(const gxRectangle *target, 
  7886.                                              const gxPoint *test);
  7887. target    A pointer to the rectangle to test as the container.
  7888. test    A pointer to the point to test for inclusion.
  7889. function result    A Boolean value indicating whether the point intersects the rectangle.
  7890. DESCRIPTION
  7891. The GXTouchesRectanglePoint function returns true as its function result if the point specified by the test parameter lies within or on the edge of the rectangle specified by the target parameter, and returns false otherwise.
  7892. Notice that the parameters to this function are not shapes; they are pointers to a gxPoint and to a gxRectangle structure.
  7893. ERRORS, WARNINGS, AND NOTICESErrors    
  7894. parameter_is_nil    
  7895.  
  7896. SEE ALSO
  7897. For a discussion of the gxPoint and gxRectangle data structures, see Chapter 2, “Geometric Shapes,” in this book.
  7898. To determine if a rectangle intersects a shape, use the GXTouchesBoundsShape function, described in the next section.
  7899. To determine if a rectangle contains a shape, use the GXContainsBoundsShape function, described on page 4-85.
  7900. GXTouchesBoundsShape  
  7901.  
  7902. You can use the GXTouchesBoundsShape function to determine if a rectangle and a shape intersect.
  7903. gxBoolean GXTouchesBoundsShape(const gxRectangle *target, 
  7904.                                          gxShape test);
  7905. target    A pointer to the rectangle to test for intersection with a shape.
  7906. test    A reference to the shape to test for intersection with the rectangle.
  7907. function result    A Boolean value indicating whether the shape intersects the rectangle.
  7908. DESCRIPTION
  7909. The GXTouchesBoundsShape function returns true as its function result if the rectangle specified by the target parameter intersects the shape specified by the test parameter—even if they share only an edge or a point—and returns false otherwise.
  7910. This function does consider the shape fill, the style modifications, and the transform mapping of the test shape. Only areas that are drawn are considered when determining intersection.
  7911. ERRORS, WARNINGS, AND NOTICESErrors    
  7912. out_of_memory    
  7913. shape_is_nil    
  7914. parameter_is_nil    
  7915.  
  7916. SEE ALSO
  7917. For an example of this function, see “Determining Whether Two Shapes Touch” beginning on page 4-47.
  7918. For a discussion of shape fills, see Chapter 2, “Geometric Shapes,” in this book.
  7919. For a discussion of style modificiations, see Chapter 3, “Geometric Styles,” in this book.
  7920. For a discussion of transform mappings, see the chapter “Transform Objects” in Inside Macintosh: QuickDraw GX Objects.
  7921. To determine if a rectangle intersects a point, use the GXTouchesRectanglePoint function, described on page 4-80.
  7922. To determine if a rectangle contains a shape, use the GXContainsBoundsShape function, described on page 4-85.
  7923. To determine if two shapes intersect, use the GXTouchesShape function, described in the next section.
  7924. GXTouchesShape  
  7925.  
  7926. You can use the GXTouchesShape function to determine if two shapes intersect.
  7927. gxBoolean GXTouchesShape(gxShape target, gxShape test);
  7928. target    A reference to one shape to test for intersection with another.
  7929. test    A reference to the other shape to test for intersection.
  7930. function result    A Boolean value indicating whether the shapes intersect.
  7931. DESCRIPTION
  7932. The GXTouchesShape function returns true as its function result if the shape specified by the target parameter intersects the shape specified by the test parameter—even if they share only an edge or a point—and returns false otherwise.
  7933. This function does consider the shape fill, the style modifications, and the transform mapping of the target and test shapes. Only areas that are drawn are considered when determining intersection. 
  7934. For example, if the target shape has an even-odd fill and contains an overlapping contour, then the shape has an internal area that is not drawn. If the test shape lies entirely within this area, the GXTouchesShape function returns false. 
  7935. As another example, if the test shape lies entirely within the target shape, but the target shape has an inverse shape fill, the GXTouchesShape function returns false.
  7936. ERRORS, WARNINGS, AND NOTICESErrors    
  7937. out_of_memory    
  7938. shape_is_nil    
  7939. clip_to_frame_shape_unimplemented    
  7940.  
  7941. SEE ALSO
  7942. For examples of this function, see “Determining Whether Two Shapes Touch” beginning on page 4-47.
  7943. For a discussion of shape fills, see Chapter 2, “Geometric Shapes,” in this book. 
  7944. For a discussion of style modificiations, see Chapter 3, “Geometric Styles,” in this book. 
  7945. For a discussion of transform mappings, see the chapter “Transform Objects” in Inside Macintosh: QuickDraw GX Objects.
  7946. To determine if a rectangle intersects a shape, use the GXTouchesBoundsShape function, described on page 4-81.
  7947. To determine if a shape contains another shape, use the GXContainsShape function, described on page 4-86.
  7948. Determining Whether One Shape Contains Another
  7949.  
  7950. The functions described in this section determine if one area contains another.
  7951. The GXContainsRectangle function determines whether the area covered by one rectangle contains the area covered by another.
  7952. The GXContainsBoundsShape function determines whether the area covered by a rectangle contains the area covered by a shape.
  7953. The GXContainsShape function determines whether the area covered by one shape contains the area covered by another.
  7954. GXContainsRectangle  
  7955.  
  7956. You can use the GXContainsRectangle function to determine if one rectangle contains another.
  7957. gxBoolean GXContainsRectangle(const gxRectangle *container, 
  7958.                                       const gxRectangle *test);
  7959. container    A pointer to the rectangle to test as the container.
  7960. test    A pointer to the rectangle to test for inclusion.
  7961. function result    A Boolean value indicating whether the container rectangle contains the test rectangle.
  7962. DESCRIPTION
  7963. The GXContainsRectangle function returns true as its function result if the rectangle specified by the test parameter lies within the rectangle specified by the target parameter, and false otherwise.
  7964. This function may return true even if the container and test rectangles share one or more edges. This function returns true even if the container and test rectangles are defined by the same coordinates.
  7965. Notice that the parameters to this function are not shapes; they are pointers to gxRectangle structures.
  7966. ERRORS, WARNINGS, AND NOTICESErrors    
  7967. parameter_is_nil    
  7968.  
  7969. SEE ALSO
  7970. For a discussion of the gxRectangle data structure, see Chapter 2, “Geometric Shapes,” in this book.
  7971. To determine if a rectangle contains a point, use the GXTouchesRectanglePoint function, described on page 4-80.
  7972. To determine if a rectangle contains a shape, use the GXContainsBoundsShape function, described in the next section.
  7973. GXContainsBoundsShape  
  7974.  
  7975. You can use the GXContainsBoundsShape function to determine if a rectangle contains a shape or a particular contour of a shape.
  7976. gxBoolean GXContainsBoundsShape(const gxRectangle *container, 
  7977.                                            gxShape test, long index);
  7978. container    A pointer to the rectangle to test as the container.
  7979. test    A reference to the shape containing the contour to test for inclusion.
  7980. index    The index of the contour to test for inclusion. You may specify a value of 0 to indicate you want to test the entire shape for inclusion.
  7981. function result    A Boolean value indicating whether the container rectangle contains the specified contour of the test shape.
  7982. DESCRIPTION
  7983. The GXContainsBoundsShape function returns true as its function result if the rectangle specified by the container parameter contains the contour indicated by the index parameter of the shape specified by the test parameter and returnes false otherwise.
  7984. This function may return true even if the container rectangle and the indicated contour of the test shape share one or more edges.
  7985. This function does consider the shape fill, the style modifications, and the transform mapping of the test shape. Only areas that are drawn are considered when determining whether the container rectangle contains the specified contour.
  7986. ERRORS, WARNINGS, AND NOTICESErrors    
  7987. parameter_is_nil    
  7988.  
  7989. SEE ALSO
  7990. For a discussion of shape fills, see Chapter 2, “Geometric Shapes,” in this book.
  7991. For a discussion of style modificiations, see Chapter 3, “Geometric Styles,” in this book.
  7992. For a discussion of transform mappings, see the chapter “Transform Objects” of Inside Macintosh: QuickDraw GX Objects.
  7993. To determine if a rectangle intersects a shape, use the GXTouchesBoundsShape function, described on page 4-81.
  7994. To determine if a shape contains another shape, use the GXContainsShape function, described in the next section.
  7995. GXContainsShape  
  7996.  
  7997. You can use the GXContainsShape function to determine if the area covered by a shape contains the area covered by another shape.
  7998. gxBoolean GXContainsShape(gxShape container, gxShape test);
  7999. container    A reference to the shape to test as the container.
  8000. test    A reference to the shape to test for inclusion.
  8001. function result    A Boolean value indicating whether the container shape contains the test shape.
  8002. DESCRIPTION
  8003. The GXContainsShape function returns true as its function result if the shape specified by the container parameter contains the shape specified by the test parameter, and returns false otherwise.
  8004. This function may return true even if the container shape and the test shape share one or more edges; it will definitely return true if they are the same shape.
  8005. This function does consider the shape fill, the style modifications, and the transform mapping of the container and test shapes. Only areas that are drawn are considered when determining whether the container shape contains the test shape. 
  8006. The container shape must have one of the solid shape fills (even-odd, winding, inverse even-odd, or inverse winding). The test shape may have any shape fill.
  8007. If the test shape has a framed shape fill, this function returns true if the frame lies entirely within the area of the container shape, or along the edges of the container shape. As a result, a filled shape contains its own frame.
  8008. ERRORS, WARNINGS, AND NOTICESErrors    
  8009. out_of_memory    
  8010.  
  8011. SEE ALSO
  8012. For examples of this function, see “Determining Whether One Shape Contains Another” beginning on page 4-51.
  8013. For a discussion of shape fills, see Chapter 2, “Geometric Shapes,” in this book.
  8014. For a discussion of style modificiations, see Chapter 3, “Geometric Styles,” in this book.
  8015. For a discussion of transform mappings, see the “Transform Objects” chapter of Inside Macintosh: QuickDraw GX Objects.
  8016. To determine if a rectangle contains a shape, use the GXContainsBoundsShape function, described on page 4-85.
  8017. To determine if one shape intersects another, use the GXTouchesShape function, described on page 4-82.
  8018. Performing Geometric Arithmetic with Shapes
  8019.  
  8020. QuickDraw GX provides six arithmetic operations you can apply to geometric shapes: intersection, union, difference, reverse difference, exclusion, and inversion.
  8021. The GXIntersectRectangle and GXUnionRectangle perform the interesection and union operations on rectangles.
  8022. The other functions described in this section perform the arithmetic operations on shapes:
  8023. n    The GXIntersectShape function finds the area common to the shapes.
  8024. n    The GXUnionShape function finds the smallest area that contains both the shapes.
  8025. n    The GXDifferenceShape function finds the area covered by the first shape which is not covered by the second shape.
  8026. n    The GXReverseDifferenceShape function finds the area covered by the second shape that is not covered by the first shape.
  8027. n    The GXExcludeShape fucntion finds the area covered by one shape or the other, but not by both.
  8028. n    The GXInvertShape function finds the area not covered by a shape.
  8029. GXIntersectRectangle  
  8030.  
  8031. You can use the GXIntersectRectangle function to find the intersection of two rectangles.
  8032. gxBoolean GXIntersectRectangle(gxRectangle *target, 
  8033.                                         const gxRectangle *source, 
  8034.                                         const gxRectangle *operand);
  8035. target    On output, the intersection of the source and operand rectangles. You may specify the value nil for this parameter if you do not want the intersection to be calculated.
  8036. source    A pointer to one of the rectangles to intersect.
  8037. operand    A pointer to the other rectangle to intersect.
  8038. function result    A Boolean value indicating whether the rectangles intersect.
  8039. DESCRIPTION
  8040. The GXIntersectRectangle function returns true as its function result if the source rectangle and the operand rectangle intersect, and returns false otherwise.
  8041. If you provide a pointer for the target parameter that is not nil, this function returns the intersection of the source and operand rectangles in the rectangle pointed to by the target parameter.
  8042. If the source and operand rectangles do not intersect, the function returns false and does not alter the target rectangle.
  8043. If the source rectangle and the operand rectangle do not intersect but merely share an edge, this function returns false and does not affect the target rectangle.
  8044. You may specify the source rectangle or the operand rectangle as the target rectangle. In this case, the function calculates the intersection of the original rectangles and then places the calculated intersection into the source or operand rectangle, as specified.
  8045. Notice that the parameters to this function are not shapes; they are pointers to gxRectangle data structures.
  8046. ERRORS, WARNINGS, AND NOTICESErrors    
  8047. parameter_is_nil    
  8048.  
  8049. SEE ALSO
  8050. For a discussion of the gxRectangle data structure, see Chapter 2, “Geometric Shapes.”
  8051. For a discussion of geometric arithmetic, see “Geometric Arithmetic” beginning on page 4-19.
  8052. To find the intersection of two shapes, use the GXIntersectShape function, described on page 4-89.
  8053. To find the union of two rectangles, use the GXUnionRectangle function, described in the next section.
  8054. GXUnionRectangle  
  8055.  
  8056. You can use the GXUnionRectangle function to find the smallest rectangle that contains two other rectangles.
  8057. gxRectangle *GXUnionRectangle(gxRectangle *target, 
  8058.                                       const gxRectangle *source, 
  8059.                                       const gxRectangle *operand);
  8060. target    The smallest rectangle containing both the source and operand rectangles.
  8061. source    A pointer to one of the rectangles to combine.
  8062. operand    A pointer to the other rectangle to combine.
  8063. function result    The smallest rectangle containing both the source and operand rectangles. (This rectangle is the same as the rectangle returned in the target parameter.)
  8064. DESCRIPTION
  8065. The GXUnionRectangle function calculates the smallest rectangle containing both the source rectangle and the operand rectangle and stores the results in target parameter. This function also returns the calculated rectangle as its function result.
  8066. You may specify the source rectangle or the operand rectangle as the target rectangle. In this case, the function calculates the smallest rectangle containing both of the original rectangles and then places the calculated rectangle into the source or operand rectangle, as specified.
  8067. Notice that the parameters to this function are not shapes, but pointers to the gxPoint and to the gxRectangle data structures.
  8068. ERRORS, WARNINGS, AND NOTICESErrors    
  8069. parameter_is_nil    
  8070.  
  8071. SEE ALSO
  8072. For a discussion of the gxRectangle data structure, see Chapter 2, “Geometric Shapes,” in this book.
  8073. For a discussion of geometric arithmetic, see “Geometric Arithmetic” beginning on page 4-19.
  8074. To find the intersection of two rectangles, use the GXIntersectRectangle function, described in this previous section.
  8075. To find the union of two shapes, use the GXUnionShape function, described on page 4-91.
  8076. GXIntersectShape  
  8077.  
  8078. You can use the GXIntersectShape function to find the intersection of two shapes.
  8079. void GXIntersectShape(gxShape target, gxShape operand);
  8080. target    On input, a reference to one of the shapes to intersect. On output, a reference to the intersection of the input target shape and the operand shape.
  8081. operand    A reference to the other shape to intersect.
  8082. DESCRIPTION
  8083. The GXIntersectShape function finds the intersection of the target shape and the operand shape and stores the result in the target shape. If the original target shape and the operand shape do not intersect, the resulting target shape is an empty shape.
  8084. If the target shape and the operand shape do not intersect but share an edge, and if both are filled, this function returns false and the resulting target shape is an empty shape. However, you can find the intersection a filled shape and a framed shape—the result being a framed shape.
  8085. This function does consider the shape fill, the style modifications, and the transform mapping of the target and test shapes. Only areas that are drawn are considered when determining intersection. 
  8086. Implementation Note
  8087. Version 1.0 of QuickDraw GX does not allow intersections of two framed shapes. Therefore, the operand shape must have one of the solid fills (even-odd, winding, inverse even-odd, or inverse winding) or no fill.u
  8088. ERRORS, WARNINGS, AND NOTICESErrors    
  8089. out_of_memory    
  8090. shape_is_nil    
  8091. fill_type_not_allowed    
  8092. number_of_contours_exceeds_implementation_limit    
  8093. number_of_points_exceeds_implementation_limit    
  8094. size_of_path_exceeds_implementation_limit    
  8095. size_of_polygon_exceeds_implementation_limit    
  8096. shape_access_not_allowed    
  8097. clip_to_frame_shape_unimplemented    
  8098. Warnings    
  8099. shape_operator_may_not_be_a_bitmap    
  8100. shape_operator_may_not_be_a_picture    
  8101. shape_access_not_allowed    
  8102. unable_to_traverse_open_contour_that_starts_or_ends_off_the_curve    
  8103. character_substitution_took_place    
  8104. font_substitution_took_place    
  8105.  
  8106. SEE ALSO
  8107. For an example of this function, see “Performing Geometric Arithmetic With Shapes” beginning on page 4-53.
  8108. For a discussion of geometric arithmetic, see “Geometric Arithmetic” beginning on page 4-19.
  8109. For a discussion of shape fills, see Chapter 2, “Geometric Shapes,” in this book.
  8110. For a discussion of style modificiations, see Chapter 3, “Geometric Styles,” in this book.
  8111. For a discussion of transform mappings, see the chapter “Transform Objects” in Inside Macintosh: QuickDraw GX Objects.
  8112. To determine if two shapes intersect, use the GXTouchesShape function, described on page 4-82.
  8113. To find the union of two shapes, use the GXUnionShape function, described in the next section.
  8114. GXUnionShape  
  8115.  
  8116. You can use the GXUnionShape function to find the union of two shapes.
  8117. void GXUnionShape(gxShape target, gxShape operand);
  8118. target    On input, a reference to one of the shapes to combine. On output, a reference to the union of the input target shape and the operand shape.
  8119. operand    A reference to the other shape to combine.
  8120. DESCRIPTION
  8121. The GXUnionShape function finds the union of the target shape and the operand shape and stores the result in the target shape.
  8122. This function does consider the shape fill, the style modifications, and the transform mapping of the target and test shape. Only areas that are drawn are considered when calculating the union. 
  8123. If the target shape has one of the frame fills (open frame or closed frame), the operand shape cannot have one of the solid fills (even-odd, winding, inverse even-odd, or inverse winding). Similarly, if the target shape has one of the solid fills, the operand shape cannot have one of the framed fills.
  8124. ERRORS, WARNINGS, AND NOTICESErrors    
  8125. out_of_memory    
  8126. shape_is_nil    
  8127. shape_fill_not_allowed    
  8128. number_of_contours_exceeds_implementation_limit    
  8129. number_of_points_exceeds_implementation_limit    
  8130. size_of_path_exceeds_implementation_limit    
  8131. size_of_polygon_exceeds_implementation_limit    
  8132. gxShape_access_not_allowed    
  8133. clip_to_frame_gxShape_unimplemented    
  8134. Warnings    
  8135. shape_operater_may_not_be_a_bitmap    
  8136. shape_operater_may_not_be_a_picture    
  8137. shape_access_not_allowed    
  8138. unable_to_traverse_open_contour_that_starts_or_ends_off_the_curve    
  8139. character_substitution_took_place    
  8140. font_substitution_took_place    
  8141.  
  8142. SEE ALSO
  8143. For examples of this function, see “Performing Geometric Arithmetic With Shapes” beginning on page 4-53.
  8144. For a discussion of geometric arithmetic, see “Geometric Arithmetic” beginning on page 4-19.
  8145. For a discussion of shape fills, see Chapter 2, “Geometric Shapes.”
  8146. For a discussion of style modificiations, see Chapter 3, “Geometric Styles.”
  8147. For a discussion of transform mappings, see Inside Macintosh: QuickDraw GX Objects.
  8148. To find the intersection of two shapes, use the GXIntersectShape function, described on page 4-89.
  8149. GXDifferenceShape  
  8150.  
  8151. You can use the GXDifferenceShape procedure to find the geometric difference between two shapes.
  8152. void GXDifferenceShape(gxShape target, gxShape operand);
  8153. target    On input, a reference to the shape to subract from. On output, a reference to a shape describing the difference between the two shapes.
  8154. operand    A reference to the shape to subtract.
  8155. DESCRIPTION
  8156. The GXDifferenceShape function subtracts the operand shape from the target shape and stores the result in the target shape. 
  8157. The initial target shape does not have to contain the operand shape; the result of this function is the intersection of the target and operand shapes subtracted from the target shape.
  8158. This function does consider the shape fill, the style modifications, and the transform mapping of the target and test shapes: only areas that are drawn are considered when calculating the difference. 
  8159. The operand shape cannot have one of the framed shape fills (open-frame or closed-frame). The target shape can have one of the framed fills; in this case, the resulting shape is the part of the frame that does not lie within the operand shape.
  8160. ERRORS, WARNINGS, AND NOTICESErrors    
  8161. out_of_memory    
  8162. shape_is_nil    
  8163. fill_type_not_allowed    
  8164. number_of_contours_exceeds_implementation_limit    
  8165. number_of_points_exceeds_implementation_limit    
  8166. size_of_path_exceeds_implementation_limit    
  8167. size_of_polygon_exceeds_implementation_limit    
  8168. shape_access_not_allowed    
  8169. clip_to_frame_shape_unimplemented    
  8170. Warnings    
  8171. shape_operator_may_not_be_a_gxBitmap    
  8172. shape_operator_may_not_be_a_picture    
  8173. shape_access_not_allowed    
  8174. unable_to_traverse_open_contour_that_starts_or_ends_off_the_curve    
  8175. character_substitution_took_place    
  8176. font_substitution_took_place    
  8177.  
  8178. SEE ALSO
  8179. For examples of this function, see “Performing Geometric Arithmetic With Shapes” beginning on page 4-53.
  8180. For a discussion of geometric arithmetic, see <xref>.
  8181. For a discussion of shape fills, see Chapter 2, “Geometric Shapes,” in this book.
  8182. For a discussion of style modificiations, see Chapter 3, “Geometric Styles,” in this book.
  8183. For a discussion of transform mappings, see Inside Macintosh: QuickDraw GX Objects.
  8184. For information about related routines, see the description of the GXIntersectShape function on page 4-89, the GXUnionShape function on page 4-91, and the GXReverseDifferenceShape function in the next section.
  8185. GXReverseDifferenceShape  
  8186.  
  8187. You can use the GXReverseDifferenceShape function to find the geometric difference between two shapes.
  8188. void GXReverseDifferenceShape(gxShape target, gxShape operand);
  8189. target    On input, a reference to the shape to subtract. On output, a reference to a shape describing the difference between the two shapes.
  8190. operand    A reference to the shape to subtract from.
  8191. DESCRIPTION
  8192. The GXReverseDifferenceShape function subtracts the target shape from the operand shape and stores the result in the target shape. 
  8193. The initial operand shape does not have to contain the target shape; the result of this function is the intersection of the target and operand shapes subtracted from the operand shape.
  8194. This function does consider the shape fill, the style modifications, and the transform mapping of the target and test shapes. Only areas that are drawn are considered when calculating the difference. 
  8195. Neither the target shape nor the operand shape can be framed.
  8196. ERRORS, WARNINGS, AND NOTICESErrors    
  8197. out_of_memory    
  8198. shape_is_nil    
  8199. fill_type_not_allowed    
  8200. number_of_contours_exceeds_implementation_limit    
  8201. number_of_points_exceeds_implementation_limit    
  8202. size_of_path_exceeds_implementation_limit    
  8203. size_of_polygon_exceeds_implementation_limit    
  8204. shape_access_not_allowed    
  8205. clip_to_frame_gxShape_unimplemented    
  8206. Warnings    
  8207. shape_operater_may_not_be_a_gxBitmap    
  8208. shape_operater_may_not_be_a_picture    
  8209. shape_access_not_allowed    
  8210. unable_to_traverse_open_contour_that_starts_or_ends_off_the_curve    
  8211. character_substitution_took_place    
  8212. font_substitution_took_place    
  8213.  
  8214. SEE ALSO
  8215. For examples of this function, see “Performing Geometric Arithmetic With Shapes” beginning on page 4-53.
  8216. For a discussion of geometric arithmetic, see “Geometric Arithmetic” beginning on page 4-19.
  8217. For a discussion of shape fills, see Chapter 2, “Geometric Shapes,” in this book.
  8218. For a discussion of style modificiations, see Chapter 3, “Geometric Styles,” in this book.
  8219. For a discussion of transform mappings, see the chapter “Transform Objects” in Inside Macintosh: QuickDraw GX Objects.
  8220. For information about related functions, see the description of the GXIntersectShape function on page 4-89, the GXUnionShape function on page 4-91, and the GXDifferenceShape function on page 4-92.
  8221. GXExcludeShape  
  8222.  
  8223. You can use the GXExcludeShape function to the exclusive-or of two shapes.
  8224. void GXExcludeShape(gxShape target, gxShape operand);
  8225. target    On input, a reference to one of the shapes on which to perform the exclusive-or operation. On output, a reference to a shape describing the exclusive-or of the two shapes.
  8226. operand    A reference to the other shape on which to perform the exclusive-or operation.
  8227. DESCRIPTION
  8228. The GXExcludeShape function performs an exclusive-or operation on the target and operand shapes, and stores the result in the target shape.
  8229. The exclusion of two shapes (the result of the exclusive-or operation) is the area contained by the union of the two shapes less the area contained by the intersection of the two shapes.
  8230. This function does consider the shape fill, the style modifications, and the transform mapping of the target and test shapes. Only areas that are drawn are considered when calculating the difference. 
  8231. Neither the target shape nor the operand shape may have one of the framed fills (open-frame or closed-frame).
  8232. ERRORS, WARNINGS, AND NOTICESErrors    
  8233. out_of_memory    
  8234. shape_is_nil    
  8235. fill_type_not_allowed    
  8236. number_of_contours_exceeds_implementation_limit    
  8237. number_of_points_exceeds_implementation_limit    
  8238. size_of_path_exceeds_implementation_limit    
  8239. size_of_polygon_exceeds_implementation_limit    
  8240. gxShape_access_not_allowed    
  8241. clip_to_frame_shape_unimplemented    
  8242. Warnings    
  8243. shape_operator_may_not_be_a_gxBitmap    
  8244. shape_operator_may_not_be_a_picture    
  8245. shape_access_not_allowed    
  8246. unable_to_traverse_open_contour_that_starts_or_ends_off_the_curve    
  8247. character_substitution_took_place    
  8248. font_substitution_took_place    
  8249.  
  8250. SEE ALSO
  8251. For examples of this function, see “Performing Geometric Arithmetic With Shapes” beginning on page 4-53.
  8252. For a discussion of geometric arithmetic, see “Geometric Arithmetic” beginning on page 4-19.
  8253. For a discussion of shape fills, see Chapter 2, “Geometric Shapes,” in this book.
  8254. For a discussion of style modificiations, see Chapter 3, “Geometric Styles,” in this book.
  8255. For a discussion of transform mappings, see the chapter “Transform Objects” in Inside Macintosh: QuickDraw GX Objects.
  8256. For information about related functions, see the description of the GXIntersectShape function on page 4-89, the GXUnionShape function on page 4-91, the GXDifferenceShape function on page 4-92, and the GXReverseDifferenceShape function on page 4-94.
  8257. GXInvertShape  
  8258.  
  8259. You can use the GXInvertShape function to invert a shape.
  8260. void GXInvertShape(gxShape target);
  8261. target    A reference to the shape to invert.
  8262. DESCRIPTION
  8263. The GXInvertShape function inverts the target shape and stores the resulting shape into the target shape. Typically, this function changes the shape fill of the target shape. It also converts empty shapes to full shapes and full shapes to empty shapes.
  8264. The target shape may not have one of the framed shape fills (open-frame or closed-frame).
  8265. ERRORS, WARNINGS, AND NOTICESErrors    
  8266. out_of_memory    
  8267. shape_is_nil    
  8268. shape_cannot_be_inverted    
  8269. Warnings    
  8270. shape_access_not_allowed    
  8271.  
  8272. SEE ALSO
  8273. For an example of this function, see “Performing Geometric Arithmetic With Shapes” beginning on page 4-53.
  8274. For a discussion of geometric arithmetic, see “Geometric Arithmetic” beginning on page 4-19.
  8275. For a discussion of shape fills, see Chapter 2, “Geometric Shapes,” in this book.
  8276.  
  8277.  
  8278. Summary of Geometric Operations
  8279.  
  8280. Constants and Data Types
  8281.  
  8282. Contour Directions
  8283. enum gxContourDirections {
  8284.     gxCounterclockwiseDirection,
  8285.     gxClockwiseDirection
  8286. };
  8287. typedef long gxContourDirection;
  8288. Functions
  8289.  
  8290. Editing Shape Direction
  8291. void GXReverseShape    (gxShape target, long contour);
  8292. gxContourDirection GXGetShapeDirection
  8293. (gxShape source, long contour);
  8294. Breaking Shape Contours
  8295. void GXBreakShape    (gxShape target, long index);
  8296. Reducing and Simplifying Shapes
  8297. void GXReduceShape    (gxShape target, long contour);
  8298. void GXSimplifyShape    (gxShape target);
  8299. Incorporating Style Information into Shape Geometries
  8300. void GXPrimitiveShape    (gxShape target);
  8301. Finding Geometric Information About Shapes
  8302. gxWide *GXGetShapeLength    (gxShape source, long index, gxWide *length);
  8303. gxPoint *GXShapeLengthToPoint
  8304. (gxShape target, long index, fixed length, 
  8305. gxPoint *location, gxPoint *tangent);
  8306. gxWide *GXGetShapeArea    (gxShape source, long index, gxWide *area);
  8307. gxPoint *GXGetShapeCenter    (gxShape source, long index, gxPoint *center);
  8308. Getting and Setting Shape Bounds
  8309. gxRectangle *GXGetShapeBounds
  8310. (gxShape source, long index, 
  8311. gxRectangle *bounds);
  8312. void GXSetShapeBounds    (gxShape target, const gxRectangle *newBounds);
  8313. Insetting Shapes
  8314. void GXInsetShape    (gxShape target, fixed inset);
  8315. Determining Whether Two Shapes Intersect
  8316. gxBoolean GXTouchesRectanglePoint
  8317. (const gxRectangle *target, 
  8318. const gxPoint *test);
  8319. gxBoolean GXTouchesBoundsShape
  8320. (const gxRectangle *target, gxShape test);
  8321. gxBoolean GXTouchesShape    (gxShape target, gxShape test);
  8322. Determining Whether One Shape Contains Another
  8323. gxBoolean GXContainsRectangle
  8324. (const gxRectangle *container, 
  8325. const gxRectangle *test);
  8326. gxBoolean GXContainsBoundsShape
  8327. (const gxRectangle *container, gxShape test, 
  8328. long index);
  8329. gxBoolean GXContainsShape    (gxShape container, gxShape test);
  8330. Performing Geometric Arithmetic With Shapes
  8331. gxBoolean GXIntersectRectangle
  8332. (gxRectangle *target,                                     const gxRectangle *source, 
  8333. const gxRectangle *operand);
  8334. gxRectangle *GXUnionRectangle
  8335. (gxRectangle *target, 
  8336. const gxRectangle *source, 
  8337. const gxRectangle *operand);
  8338. void GXIntersectShape    (gxShape target, gxShape operand);
  8339. void GXUnionShape    (gxShape target, gxShape operand);
  8340. void GXDifferenceShape    (gxShape target, gxShape operand);
  8341. void GXReverseDifferenceShape
  8342. (gxShape target, gxShape operand);
  8343. void GXExcludeShape    (gxShape target, gxShape operand);
  8344. void GXInvertShape    (gxShape target);
  8345. Listing 5-0
  8346. Table 5-0
  8347. Bitmap Shapes
  8348. Contents
  8349. About Bitmap Shapes5-3
  8350. Bitmap Geometries5-4
  8351. Bitmap Styles and Inks5-7
  8352. Bitmap Transforms5-8
  8353. Bitmaps and View Devices5-10
  8354. Using Bitmap Shapes5-13
  8355. Creating and Drawing Bitmaps5-13
  8356. Creating Black-and-White Bitmaps5-14
  8357. Creating Color Bitmaps5-19
  8358. Dithering and Halftoning Bitmaps5-28
  8359. Applying Transfer Modes to Bitmaps5-30
  8360. Converting Other Types of Shapes to Bitmaps5-32
  8361. Applying Transformations to Bitmaps5-35
  8362. Creating Bitmaps With Disk-Based Pixel Images5-40
  8363. Creating Bitmaps Offscreen5-42
  8364. Editing Parts of a Bitmap5-49
  8365. Applying Functions Described Elsewhere to Bitmap Shapes5-51
  8366. Functions That Post Errors or Warnings When Applied to Bitmap Shapes5-51
  8367. Shape-Related Functions Applicable to Bitmap Shapes5-53
  8368. Geometric Operations Applicable to Bitmap Shapes5-54
  8369. Style-Related Functions Applicable to Bitmap Shapes5-55
  8370. Ink-Related and Color-Related Functions Applicable to Bitmap Shapes5-55
  8371. Transform-Related Functions Applicable to Bitmap Shapes5-55
  8372. View-Related Functions That Can Be Applied to Bitmap Shapes5-57
  8373. Bitmap Shapes Reference5-58
  8374. Data Types5-58
  8375. The Bitmap Geometry Structure5-58
  8376. The Long Rectangle Structure5-60
  8377. Constants For Bitmaps With Disk-Based Pixel Images5-60
  8378. Bitmap Data Source Alias Structure5-61
  8379. Functions5-61
  8380. Creating Bitmaps5-62
  8381. GXNewBitmap 5-62
  8382. Getting and Setting Bitmap Geometries5-64
  8383. GXGetBitmap 5-64
  8384. GXSetBitmap 5-65
  8385. Editing Bitmaps5-67
  8386. GXGetShapePixel 5-68
  8387. GXSetShapePixel 5-69
  8388. GXGetBitmapParts 5-70
  8389. GXSetBitmapParts 5-71
  8390. Drawing Bitmaps5-72
  8391. GXDrawBitmap 5-73
  8392. Checking Bitmap Colors5-74
  8393. GXCheckBitmapColor5-74
  8394. Summary of Bitmap Shapes5-76
  8395. Data Types5-76
  8396. Functions5-77
  8397. Bitmap Shapes
  8398. QuickDraw GX provides four basic types of shapes:
  8399. n    geometric shapes
  8400. n    typographic shapes
  8401. n    bitmap shapes
  8402. n    picture shapes
  8403. This chapter describes bitmap shapes and the functions you use to manipulate them. It also discusses functions described in other chapters and shows how you can apply them to bitmap shapes.
  8404. Before you read this chapter, you should be familiar with the information in the chapter “Shape Objects” of Inside Macintosh: QuickDraw GX Objects, and you will probably want to be familiar with much of the information discussed in the chapters “Color and Color-Related Objects,” “Transform Objects,” and “View-Related Objects,” also in that book.
  8405. This chapter introduces bitmap shapes, describes bitmap geometries, and then shows how to:
  8406. n    define bitmap geometries
  8407. n    create bitmap shapes
  8408. n    draw bitmap shapes
  8409. n    manipulate the pixel image stored in a bitmap shape
  8410. n    apply transfer modes and trasnformations to bitmap shapes
  8411. n    draw other QuickDraw GX objects into a bitmap shape
  8412. n    create bitmap shapes with disk-based pixel images
  8413. n    replace a part of a bitmap shape’s pixel image
  8414.  
  8415. About Bitmap Shapes
  8416.  
  8417. Like all shapes, a bitmap shape is represented in memory by a shape object, a style object, an ink object, and a transform object. A shape object representing a bitmap shape contains the same properties as a shape object representing a geometric or typographic shape: owner count, tag list, shape type, shape fill, geometry, and so on. 
  8418. Figure 5-2 shows a graphic representation of a bitmap shape and a bitmap geometry.
  8419. Figure 5-1    A bitmap shape
  8420.  
  8421. Bitmap shapes make extensive use of their geometry property. In fact, most of the information useful to bitmap shapes is stored in their geometry—the values of the bitmap’s pixels, the dimensions of the bitmap, and the color information used by the bitmap. 
  8422. Bitmap shapes don’t make much use of their shape fill property, and they use very little of their associated style object. In fact, the only information in a style object used by bitmap shapes are the style attributes that determine whether the upper-left corner of the bitmap should be constrained to an integer grid position.
  8423. Bitmap shapes don’t use the color property of their ink object, as they store their own color information in their geometries. However, they do use the transfer mode property of their ink objects.
  8424. Bitmap shapes do make full use of their transform objects, however. For example, you can scale, skew, rotate, and clip bitmap shapes. You can also hit-test bitmap shapes, but you cannot hit-test parts of a bitmap shape, as you can for other types of shapes. For more information about transform objects and hit-testing, see the chapter “Transform Objects” of Inside Macintosh: QuickDraw GX Objects.
  8425. The next few sections discuss bitmap geometries, bitmap styles, bitmap inks, and bitmap transforms.
  8426. Bitmap Geometries
  8427.  
  8428. The geometry of a bitmap contains eight fields:
  8429. n    The pixel image, or a pointer to a two-dimensional array of pixel values. Each pixel value represents the color of one pixel of the bitmap.
  8430. n    The  bitmap position,  or the position of the upper-left corner of the bitmap. The actual position of the bitmap when drawn may differ depending on the information in the bitmap’s transform object.
  8431. n    The bitmap width, or  the number of pixels in each row of the bitmap.
  8432. n    The bitmap height, or the number of pixels in each column of the bitmap.
  8433. n    The pixel size, or the number of bits required to represent the color information for each pixel of the bitmap.
  8434. n    The bytes per row,  or the number of bytes of the pixel image that correspond to each row of the bitmap.
  8435. n    The bitmap color space, or the color space that determines how QuickDraw GX translates the bitmap’s pixel values into colors. If the bitmap has any color space except indexed space, each pixel value in the pixel image represents a color specification in this color space. If the bitmap has an indexed color space, each pixel value is interpreted using the bitmap color set.
  8436. n    The bitmap color set, or the (optional) array of color values associated with the bitmap. If the bitmap uses a color set (also called an indexed color space), each pixel value in the bitmap’s pixel image represents an index into this color set.
  8437. n    The bitmap color profile, or the color-matching information that you can specify for the device on which the bitmap was created.
  8438. QuickDraw GX enforces a few restrictions on the values of these geometry fields. For example, the pixel size of the bitmap must be a power of 2 (from 1 to 32), and it must correspond to the pixel size implicit in the bitmap color space.
  8439. The bytes per row of the bitmap must be a multiple of 2. This requirement allows for faster bitmap manipulation.
  8440. Note
  8441. Although the Macintosh platform accepts any even number of bytes per row, you might want to use a multiple of 4 bytes per row in your bitmaps to promote cross-platform compatibility.u
  8442. Sometimes you must pad a pixel image with extra bits to get an even number of bytes per row. For example, Figure 5-2 shows a small, black-and-white (1 bit per pixel) bitmap with a bitmap width of 10. The smallest number of bytes per row into which 10 bits fit is 2, so the number of bytes per row for this bitmap is 2. Although the six extra bits at the end of each row of the pixel image have values, they do not appear as pixels in the bitmap when it is drawn.
  8443. Figure 5-2    A black-and-white bitmap geometry
  8444.  
  8445. All QuickDraw GX bitmaps are actually color bitmaps. A black-and-white bitmap is simply a color bitmap with a color set containing only two colors—black and white.
  8446. Figure 5-2 shows another bitmap. In this example, the pixel size is 2; each pixel is represented by 2 bits. Since no color space has an implicit pixel size of 2, this bitmap uses a color set instead of a color space. The color set contains four shades of gray; each pixel value in the pixel image is an index into this color set. Since the bitmap width is 5 pixels and the pixel size is 2 bits per pixel, at least 10 bits are required to represent each row of the pixel image. The smallest number of bytes per row that contains 10 bits is 2 bytes, so each row of the bitmap has 16 bits total. The last 6 bits are ignored by QuickDraw GX.
  8447. Figure 5-3    A grayscale bitmap geometry
  8448.  
  8449. QuickDraw GX allows you to store bitmap’s pixel image in one of three locations:
  8450. n    You can allocate memory for the pixel image yourself. In this case, you provide QuickDraw GX with a pointer to the memory containing your pixel image. See the section “Creating and Drawing Bitmaps” beginning on page 5-13 gives examples of allocating memory for a pixel image yourself and incorporating the pixel image into bitmap a bitmap shape.
  8451. n    You can request that QuickDraw GX allocate the memory for you. In this case, you must use QuickDraw GX functions to draw into the bitmap and to edit it. If you want to edit the pixel image directly, you can use other QuickDraw GX functions to lock the image in memory and to request a pointer to it. However, if QuickDraw GX is storing the pixel image on an accelerator card, your application might not be able to edit the pixel image directly. See the section “Creating Bitmaps Offscreen” beginning on page 5-42 gives an example of requesting that QuickDraw GX allocate memory for your pixel image.
  8452. n    You can associate the bitmap with a disk-based pixel image—a pixel image stored in a disk file. In this case, you can use QuickDraw GX functions to read and draw the bitmap, but you cannot use QuickDraw GX functions to edit the bitmap. You must edit the bitmap directly using file-manipulation functions. The section “Creating Bitmaps With Disk-Based Pixel Images” beginning on page 5-40 shows how you can create a bitmap that uses a disk-based pixel image.
  8453. Bitmap Styles and Inks
  8454.  
  8455. Although bitmap shapes have style objects and ink objects, they do not make full use of the properties of these objects. Of the many properties of the style object, only the style attributes property affects bitmap shapes. In fact, only the gxSourceGridStyle and gxDeviceGridStyle style attributes affect bitmap shapes. QuickDraw GX ignores the other style attributes and the other style properties when drawing a bitmap shape. You can set the values of these properties and determine the values you have set them to, but they do not affect how the bitmap is drawn.
  8456. You can find out how the gxSourceGridStyle and gxDeviceGridStyle style attributes affect shapes, including bitmap shapes, in Chapter 3, “Geometric Styles.”
  8457. Of the ink object properties, bitmaps use the transfer mode property and ignore the color property. Since bitmap shapes have color information stored in their geometries, they do not need the color information stored in their ink objects. You can set the color of a bitmap shape’s ink object, but it does not affect how the bitmap is drawn.
  8458. The transfer mode property, on the other hand, does affect the drawing of the bitmap. QuickDraw GX applies the transfer mode as it draws each pixel of the bitmap, as shown in Figure 5-4. You can find a color version of this figure in Color Plate 1 at the front of this book.
  8459. Figure 5-4    The effect of transfer modes on bitmap shapes
  8460.  
  8461. The section “Applying Transfer Modes to Bitmaps” beginning on page 5-30 shows you how to apply a transfer mode to a bitmap shape.
  8462. Bitmap Transforms
  8463.  
  8464. Although bitmap shapes make limited use of their style and ink objects, they make full use of their transform objects. Using the transform object, you can clip bitmap shapes and apply mapping transformations to them. Some examples are shown in Figure 5-5.
  8465. Figure 5-5    The effect of mappings on bitmap shapes
  8466.  
  8467. You can find examples of how to clip and map bitmap shapes in “Applying Transformations to Bitmaps,” which begins on page 5-35, and you can find complete information about clipping and mapping in the chapter “Transform Objects” in Inside Macintosh: QuickDraw GX Objects as well as the chapter “QuickDraw GX Mathematics” in Inside Macintosh: QuickDraw GX Environment and Utilities. 
  8468. Bitmap shapes, like other types of shapes, use the gxMapTransformShape shape attribute to determine how mappings should be applied to the shape. If you set this shape attribute, applying a mapping to a bitmap shape changes the mapping matrix stored in the transform object of the bitmap shape. However, if you do not set this shape attribute, applying a mapping to a bitmap shape changes the geometry of the bitmap directly—that is, QuickDraw GX creates a completely new pixel image to represent the transformed bitmap.
  8469. Figure 5-6 compares the results of rotating a bitmap shape with and without the gxMapTransformShape shape attribute set.
  8470. Figure 5-6    The effect of the gxMapTransformShape shape attribute on bitmap mappings 
  8471.  
  8472. Each mapping that you apply to a bitmap shape that does not have its gxMapTransformShape shape attribute set results in quality degradation of the bitmap’s pixel image. If you apply multiple mappings to a bitmap shape that does not have this shape attribute set, error can arise rapidly. The section “Applying Transformations to Bitmaps,” which begins on page 5-35, gives an example of this phenomenon.
  8473. Bitmaps and View Devices
  8474.  
  8475. When you draw a shape, QuickDraw GX applies the information in the shape’s style, ink, and transform objects to the shape’s geometry and then renders the shape to the display devices that correspond to the view information contained in the shape’s transform object.
  8476. The transform object of a shape contains a list of view ports to which QuickDraw GX should draw the shape. Each view port exists in the coordinate space of a specific view group, and each view group contains view devices that share the same coordinate space. QuickDraw GX determines where the shape appears in the coordinate space of each view group. If the area of the shape when drawn overlaps the area covered by any view device in that view group, QuickDraw GX renders the shape into the bitmap attached to that view device.
  8477. Figure 5-7 depicts how this drawing mechanism works with four shapes: two path shapes, a bitmap shape, and a text shape. The two path shapes share one transform object and the bitmap shape and the text shape share a second transform object.
  8478. Both of the transform objects contain one view port in their view port list. That view port exists in a view group that also contains a view device. The view device has a bitmap shape associated with it to hold the renderings of shapes drawn to it.
  8479. Figure 5-7    Bitmaps and view devices
  8480.  
  8481. Whenever you draw a QuickDraw GX shape, you are using this view architecture to render the shape to a display device. You can also use this view architecture to draw shapes into an offscreen bitmap—a bitmap that is not associated with a physical display device. 
  8482. The section “Creating Bitmaps Offscreen,”which begins on page 5-42 shows how you can create an offscreen bitmap, draw shapes into it, and then draw it to the screen.
  8483. You can find more information about the QuickDraw GX view architecture in the chapter “View-Related Objects” of Inside Macintosh: QuickDraw GX Objects.
  8484.  
  8485.  
  8486. Using Bitmap Shapes
  8487.  
  8488. This section shows you how to create, edit, and draw bitmap shapes. In particular, this section shows you how to 
  8489. n    create and draw black-and-white bitmaps
  8490. n    create and draw color bitmaps
  8491. n    dither and halftone bitmaps
  8492. n    apply transfer modes to bitmaps
  8493. n    convert other types of shapes to bitmap shapes
  8494. n    apply transformations to bitmaps
  8495. n    create offscreen bitmaps
  8496. n    edit sections of bitmaps
  8497. Bitmap shape geometries use a gxPoint structure to indicate the initial position of the bitmap. Since a gxPoint structure contains two fixed-point values (type fixed),  the sample functions in this section must convert integer constants to fixed-point constants when specifying bitmap positions. QuickDraw GX provides the GXIntToFixed macro to perform this conversion:
  8498. #define GXIntToFixed(a) ((fixed)(a) << 16)
  8499. QuickDraw GX also provides the ff macro as a convenient alias:
  8500. #define ff(a) GXIntToFixed(a)
  8501. Creating and Drawing Bitmaps
  8502.  
  8503. QuickDraw GX provides a number of methods to create and draw bitmaps. For example, you can
  8504. n    define a bitmap geometry and draw it without creating a bitmap shape
  8505. n    define a bitmap geometry, encapsulate it in a bitmap shape, and draw the bitmap shape
  8506. n    create another type of shape, convert it to a bitmap shape, perform any desired bitmap editing, and draw the bitmap shape
  8507. n    create an offscreen bitmap, draw shapes to it, and then copy the offscreen bitmap to the screen
  8508. n    unflatten a bitmap shape that was created earlier and stored to disk or that was created by another application
  8509. n    convert an original QuickDraw bitmap to a QuickDraw GX bitmap shape
  8510. The next two sections, “Creating Black-and-White Bitmaps,” which begins on page 5-14, and “Creating Color Bitmaps,” which begins on page 5-19, show you how to create bitmaps by specifying the bitmap geometry yourself.
  8511. The section “Converting Other Types of Shapes to Bitmaps,” which begins on page 5-32, shows you how you can create a bitmap shape containing a bitmap representation of a QuickDraw GX shape.
  8512. The section “Creating Bitmaps Offscreen,” which begins on page 5-42, shows you how you can draw other shapes into the pixel image of a bitmap shape. You can use this method to create a bitmap representation of multiple QuickDraw GX shapes.
  8513. For information about flattening and unflattening bitmap shapes, see the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  8514. Creating Black-and-White Bitmaps
  8515.  
  8516. You create a black-and-white bitmap by creating a bitmap shape with a pixel size of 1. To do this, you can define a pixel image, fill the fields of a bitmap geometry structure, and create a bitmap shape using the GXNewBitmap function.
  8517. Listing 5-1 shows a complete sample function that defines a black-and-white bitmap geometry, creates a bitmap shape, draws the shape, and disposes of it.
  8518. Listing 5-1    Creating a black-and-white bitmap
  8519.  
  8520. void CreateBlackAndWhiteBitmap(void)
  8521. {
  8522.     gxShape  aBitmapShape;
  8523.  
  8524.     gxBitmap aBitmapGeometry;
  8525.     gxPoint initialPosition = {ff(20), ff(40)};
  8526.     
  8527.     const char envelopeImage[] = {0x7F, 0xFF, 0xFF, 0xFE,
  8528.                                                0xC0, 0x00, 0x00, 0x03,
  8529.                                                0xB0, 0x00, 0x00, 0x0D,
  8530.                                                0x8C, 0x00, 0x00, 0x31,
  8531.                                                0x83, 0x00, 0x00, 0xC1,
  8532.                                                0x80, 0xC0, 0x03, 0x01,
  8533.                                                0x80, 0x30, 0x0C, 0x01,
  8534.                                                0x80, 0x0C, 0x30, 0x01,
  8535.                                                0x80, 0x33, 0xCC, 0x01,
  8536.                                                0x80, 0xC0, 0x03, 0x01,
  8537.                                                0x83, 0x00, 0x00, 0xC1,
  8538.                                                0x8C, 0x00, 0x00, 0x31,
  8539.                                                0xB0, 0x00, 0x00, 0x0D,
  8540.                                                0x7F, 0xFF, 0xFF, 0xFE};
  8541.  
  8542.     
  8543.     aBitmapGeometry.image = (char *) aSmallBitmapImage;
  8544.     
  8545.     aBitmapGeometry.width = 32;       /* width in pixels */ 
  8546.     aBitmapGeometry.height = 14;      /* height in pixels */
  8547.     aBitmapGeometry.rowBytes = 4;     /* bytes per row */
  8548.     aBitmapGeometry.pixelSize = 1;    /* bits per pixel */
  8549.     
  8550.     /* QuickDraw GX creates a black-and-white color set for you */
  8551.     aBitmapGeometry.space = gxNoSpace; 
  8552.     aBitmapGeometry.set = nil;                     
  8553.     aBitmapGeometry.profile = nil;     
  8554.  
  8555.     aBitmapShape = GXNewBitmap(&aBitmapGeometry, &initialPosition);
  8556.  
  8557.     GXDrawShape(aBitmapShape);    
  8558.     GXDisposeShape(aBitmapShape);
  8559. }
  8560. The result of this function is shown in Figure 5-2. 
  8561. Figure 5-8    A black-and-white bitmap—32 bits wide
  8562.  
  8563. The sample function from Listing 5-1 first defines a variable to hold the reference to the bitmap shape:
  8564. gxShape            aBitmapShape;
  8565. Then the sample function defines two local variables to specify the bitmap geometry:
  8566. gxPoint initialPosition = {ff(20), ff(40)};
  8567. gxBitmap aBitmapGeometry;
  8568. The initialPosition variable, which is type gxPoint, contains the initial bitmap position, and the aBitmapGeometry variable, which is type gxBitmap, contains the rest of the information about the bitmap.
  8569. The sample function then defines the bitmap’s pixel image:
  8570. const char envelopeImage[] = {0x7F, 0xFF, 0xFF, 0xFE,
  8571.                                            0xC0, 0x00, 0x00, 0x03,
  8572.                                            0xB0, 0x00, 0x00, 0x0D,
  8573.                                            0x8C, 0x00, 0x00, 0x31,
  8574.                                            0x83, 0x00, 0x00, 0xC1,
  8575.                                            0x80, 0xC0, 0x03, 0x01,
  8576.                                            0x80, 0x30, 0x0C, 0x01,
  8577.                                            0x80, 0x0C, 0x30, 0x01,
  8578.                                            0x80, 0x33, 0xCC, 0x01,
  8579.                                            0x80, 0xC0, 0x03, 0x01,
  8580.                                            0x83, 0x00, 0x00, 0xC1,
  8581.                                            0x8C, 0x00, 0x00, 0x31,
  8582.                                            0xB0, 0x00, 0x00, 0x0D,
  8583.                                            0x7F, 0xFF, 0xFF, 0xFE};
  8584. The envelopeImage variable, which is defined as an array of bytes, contains a pixel image depicting a small envelope, as shown in Figure 5-2.
  8585. To create a bitmap shape encapuslating this envelope image, the sample function fills in the eight fields of the aBitmapGeometry variable. First, it sets the image field by casting the envelopeImage variable to the correct type:
  8586. aBitmapGeometry.image = (char *) envelopeImage;
  8587. Then the sample function fills in the bitmap dimensions. The bitmap is 32 pixels wide by 14 pixels high, and there are 4 bytes of information in each row of the pixel image:
  8588. aBitmapGeometry.width = 32;       /* width in pixels */ 
  8589. aBitmapGeometry.height = 14;      /* height in pixels */
  8590. aBitmapGeometry.rowBytes = 4;     /* bytes per row */
  8591. The sample function specifies the pixel size next. Since this bitmap is black-and-white, only one bit is needed to represent each pixel of the bitmap:
  8592. aBitmapGeometry.pixelSize = 1;    /* bits per pixel */
  8593. Finally, the sample function specifies color information. Since QuickDraw GX does not provide a black-and-white color space, this bitmap needs a black-and-white color set in which pixel values of 0 represent white pixels and pixel values of 1 represent black pixels. Setting the pixelSize field to 1 and the space field to gxNoSpace indicates that QuickDraw GX should create this black-and-white color set for you.
  8594. aBitmapGeometry.space = gxNoSpace;  
  8595. aBitmapGeometry.set = nil;                      
  8596. aBitmapGeometry.profile = nil;      
  8597. Setting the space field to the value gxNoSpace always indicates that QuickDraw GX should choose a color space for you. If the pixel size were large—for example, 16 or 32—QuickDraw GX would choose an RGB color space. However, since the pixel size is 1, no appropriate color space exists, so QuickDraw GX creates a grayscale color set. The pixel size determines the size of the color set created. In this case, a pixel size of 1 dictates that the color set have two entries—an white entry for a pixel value of 0 and a black entry for a pixel value of 1. 
  8598. After you define a bitmap geometry, you can use
  8599. GXDrawBitmap(&aBitmapGeometry, &initialPosition);
  8600. to cause QuickDraw GX to
  8601. n    create a temporary bitmap shape (using the style, ink, and transform objects of the default bitmap shape)
  8602. n    draw the bitmap
  8603. n    dispose the temporary bitmap shape
  8604. You should use the GXDrawBitmap function only when you know in advance that you want to draw a bitmap only one time.
  8605. If you want to draw a bitmap more than once, you should encapsulate the bitmap geometry in a bitmap shape and then draw the bitmap shape. The sample function in Listing 5-1 uses this method:
  8606. aBitmapShape = GXNewBitmap(&aBitmapGeometry, &initialPosition);
  8607. GXDrawShape(aBitmapShape);
  8608. As with any type of QuickDraw GX shape, if you create a bitmap shape, you are responsible for disposing of it when you no longer need it. Listing 5-1 does this by calling
  8609. GXDisposeShape(aBitmapShape); 
  8610. Notice that envelope bitmap requires 4 bytes—an even number—to represent each row of the pixel image. However, to draw a similar envelope bitmap that includes two more rows of bits, as shown in Figure 5-2, the required number of bytes might seem to be 5—since 5 bytes contain 40 bits, more than enough needed to store the 34 bits per row in this image.
  8611. However, if you set the rowBytes field to 5:
  8612. aBitmapGeometry.rowBytes = 5;
  8613. both the GXDrawBitmap function and the GXNewBitmap function post the error bitmap_rowBytes_not_aligned, because the value of the rowBytes field must be an even number. 
  8614. Therefore, the value of the rowBytes field must be at least 6 for the bitmap of the envelope with a shadow. However, simply setting the rowBytes field to the value 6 with the assignment
  8615. aBitmapGeometry.rowBytes = 6;
  8616. results in the bitmap shown in Figure 5-2. 
  8617. Figure 5-9    An example of unaligned bytes per row
  8618.  
  8619. Clearly, the value of the bitmap’s rowBytes field is not aligned with the data in the bitmap’s pixel image. If you set the value of the rowBytes field to 6, you must be sure to pad the pixel image so that each row actually contains 6 bytes of information. Listing 5-2 shows a new definition of the pixel image. In this definition, each row contains one extra byte so that the total number of bytes per row is even. 
  8620. In this example, the extra bytes are initialized to the value 0x00. However, since these bytes are just padding, you can specify any values for them. As indicated by the bitmap width, QuickDraw GX ignores these extra bytes when drawing, hit-testing, or otherwise manipulating the bitmap.
  8621. Listing 5-2    A bit image with an even number of bytes per row
  8622.  
  8623. static char envelopeImage[]= {    0x7F, 0xFF, 0xFF, 0xFE, 0x50, 0x00,
  8624.                                         0xC0, 0x00, 0x00, 0x03, 0xA0, 0x00,
  8625.                                        0xB0, 0x00, 0x00, 0x0D, 0x50, 0x00,
  8626.                                        0x8C, 0x00, 0x00, 0x31, 0xA0, 0x00,
  8627.                                        0x83, 0x00, 0x00, 0xC1, 0x50, 0x00,
  8628.                                        0x80, 0xC0, 0x03, 0x01, 0xA0, 0x00,
  8629.                                        0x80, 0x30, 0x0C, 0x01, 0x50, 0x00,
  8630.                                        0x80, 0x0C, 0x30, 0x01, 0xA0, 0x00,
  8631.                                        0x80, 0x33, 0xCC, 0x01, 0x50, 0x00,
  8632.                                        0x80, 0xC0, 0x03, 0x01, 0xA0, 0x00,
  8633.                                        0x83, 0x00, 0x00, 0xC1, 0x50, 0x00,
  8634.                                        0x8C, 0x00, 0x00, 0x31, 0xA0, 0x00,
  8635.                                        0xB0, 0x00, 0x00, 0x0D, 0x50, 0x00,
  8636.                                        0x7F, 0xFF, 0xFF, 0xFE, 0xA0, 0x00,
  8637.                                        0x15, 0x55, 0x55, 0x55, 0x40, 0x00,
  8638.                                        0x0A, 0xAA, 0xAA, 0xAA, 0x80, 0x00};
  8639. With this new, padded definition of the pixel image, you can set rowBytes field to 6 so that the resulting bitmap appears as shown in Figure 5-2.
  8640. Figure 5-10    An envelope with a shadow
  8641.  
  8642. For a discussion of pixel images and bitmap geometries, see “Bitmap Geometries” beginning on page 5-4.
  8643. For more information about the GXNewBitmap function, see its description on page 5-62. For more information about the GXDrawBitmap function, see its description on page 5-74.
  8644. The next section shows you how you can create a bitmap with color information.
  8645. Creating Color Bitmaps
  8646.  
  8647. All QuickDraw GX bitmaps are actually color bitmaps. A black-and-white bitmap is simply a color bitmap with a color set containing only two colors—black and white.
  8648. The sample function in Listing 5-1 on page 5-14 creates a black-and-white bitmap geometry by
  8649. n    specifying the pixel size to be 1   
  8650. n    specifying the color space to be the gxNoSpace color space
  8651. The sample function encapsulates the geometry into a bitmap shape with this call to the GXNewBitmap function: 
  8652. aBitmapShape = GXNewBitmap(&aBitmapGeometry, &initialPosition);
  8653. Because the space field of the bitmap geometry specifies the gxNoSpace color space, the GXNewBitmap function chooses a color space for you, based on the pixel size specified in the pixelSize field. QuickDraw GX does not provide any color spaces appropriate for a pixel size of 1, so the GXNewBitmap function creates a grayscale color set with two entries—white and black.
  8654. If you specify the gxNoSpace color space with a pixel size of 2, the GXNewBitmap function creates a grayscale color set with four entries—white, light gray, dark gray, and black. After you change the pixel size to 2, you must reflect that change in the pixel image, the bitmap width, and the number of bytes per row. 
  8655. Typically, if you wanted to make a 1 bit-per-pixel bitmap into a 2 bit-per-pixel bitmap, you would
  8656. n    maintain the bitmap width, as it represents the number of pixel values—not the number of bits—per row of the bitmap
  8657. n    double the number of bytes per row to accomodate the extra bits
  8658. n    double the size of the pixel image, replacing 1-bit pixel values with 2-bit pixel values
  8659. This method allows you to maintain the size of the bitmap while allowing you to specify more possible values (colors) for each pixel.
  8660. However, an easier (if somewhat less useful) way to make a 1 bit-per-pixel bitmap into a 2 bit-per-pixel bitmap is
  8661. n    divide the bitmap width in half
  8662. n    maintain the same number of bytes per row
  8663. n    maintain the same pixel image
  8664. Let’s see what happens when you apply this simpler method for doubling the pixel size of a bitmap. Doubling the pixel size and halving the bitmap width of the envelope bitmap shown in Figure 5-2 on page 5-6 indicates that QuickDraw GX should interpret every pair of bits in the pixel image as a single pixel. Since each pixel can have one of four possible values (00, 01, 10, 11), the resulting bitmap contains four shades of gray, as shown in Figure 5-2. 
  8665. Figure 5-11    A thinner envelope bitmap with four shades of grey
  8666.  
  8667. If you double the pixel size and halve the bitmap width again, with the assignments
  8668. aBitmapGeometry.width = 9;
  8669. aBitmapGeometry.height = 16;
  8670. aBitmapGeometry.rowBytes = 6;
  8671. aBitmapGeometry.pixelSize = 4;
  8672. QuickDraw GX interprets each set of 4 bits in the pixel image as representing a single pixel of the bitmap, which means each pixel can now be represented by 16 different values (0000, 0001, 0010, and so on). Since QuickDraw GX has no predefined color space that uses a pixel size of 4, it creates for this bitmap a color set with sixteen shades of gray.
  8673. Figure 5-2 shows the resulting bitmap.
  8674. Figure 5-12    A bitmap with sixteen shades of gray
  8675.  
  8676. As the previous examples have shown, setting the space field of a bitmap geometry to the gxNoSpace constant indicates that you want QuickDraw GX to choose a color space for you. In these examples, which had 1, 2, or 3 bits per pixel, QuickDraw GX chose the gxIndexedSpace color space and created a grayscale color set with the appropriate number of color entries.
  8677. You are not limited to these grayscale color sets, however. You can create your own color set, by choosing your own set of colors for the color entries. Listing 5-3 shows how to define a simple color set with eight colors—black and white, the three primary RGB colors, and the three secondary RGB colors. 
  8678. Listing 5-3    Defining a color set
  8679.  
  8680. gxColorSet aColorSet;
  8681.  
  8682. gxSetColor newColorList[] = {
  8683.     {0xFFFF, 0xFFFF, 0xFFFF, 0},                                            /* white */
  8684.     {0xFFFF, 0,                       0,      0},                        /* red */
  8685.     {0,      0xFFFF, 0,      0},                                            /* green */
  8686.     {0,      0,      0xFFFF, 0},                                            /* blue */
  8687.     {0,      0xFFFF, 0xFFFF, 0},                                            /* cyan */
  8688.     {0xFFFF, 0,      0xFFFF, 0},                                            /* magenta */
  8689.     {0xFFFF, 0xFFFF, 0,      0},                                            /* yellow */
  8690.     {0,      0,      0,      0},                                             /* black */
  8691. };
  8692. The colors in this color set are specifed in the RGB color space, and each color contains four components—the red component, the green component, the blue component, and a fourth component, which QuickDraw GX ignores for the RGB color space. QuickDraw GX allows you to specify colors in other color spaces and with different numbers of components. For complete color-specifying information, see the chapter “Color and Color-Related Objects” in Inside Macintosh: QuickDraw GX Objects.
  8693. Once you’ve defined the color list for a color set, you create the actual color set object by using the GXNewColorSet function, which requires you to specify the color space in which you’ve specified the colors, the total number of colors, and the list of colors:
  8694. aColorSet = GXNewColorSet(gxRgbSpace, 8, newColorList);
  8695. Note
  8696. Remember, you are responsible for disposing of QuickDraw GX objects when you no longer need them, so you are responsible for disposing of this new color set.u
  8697. To use the new color set in your bitmap, you need to set the space and set fields of the bitmap geometry:
  8698. aBitmapGeometry.space = gxIndexedSpace;
  8699. aBitmapGeometry.set = aColorSet;
  8700. Setting the space field to gxIndexedSpace indicates that you are supplying the color set, rather than having QuickDraw GX create one for you.
  8701. Figure 5-13 shows the result of applying this new color set to the 4-bits-per-pixel version of the envelope bitmap. Notice that pixel values in the pixel image greater than 7 are out of the range of the color set, so QuickDraw GX maps those pixel values to the color black.
  8702. For a color version of Figure 5-13, see Color Plate 2 at the front of this book.
  8703. Figure 5-13    A bitmap with eight colors
  8704.  
  8705. Each of the previous examples in this chapter create a bitmap that uses a color set. QuickDraw GX interprets each pixel of these bitmaps as an index into a set of colors. For example, in the black-and-white bitmap that results from Listing 5-1 on page 5-14, each pixel value (single bit) of the pixel image is an index into a color set with two colors—the index of the color white is 0 and the index of the color black is 1. In the 2-bits-per-pixel example on page 5-6, each pixel value (pair of bits) in the pixel image is an index into a color set with four colors—the index of white is 0 (bits 00), the index of light gray is 1 (bits 01), the index of dark gray is 2 (bits 10), and the index of black is 3 (bits 11).
  8706. QuickDraw GX also allows you to create bitmaps that use color spaces other than indexed color spaces (that is, other than color sets). In these bitmaps, each pixel value is an actual color value instead of an index into a list of colors. The chapter “Color-Related Objects” in Inside Macintosh: QuickDraw GX Objects explains color spaces, color values, color sets, and color indexes.
  8707. One example of a bitmap for which you might want to use a color space instead of a color set is a color ramp. A color ramp is a shape that blends from one color into another. Since bitmaps are the only type of QuickDraw GX shape (except picture shapes) that allows multiple colors in one shape, you must implement color ramps as bitmap shapes.
  8708. The sample function in Listing 5-4 on page 5-24 shows how to create a simple color ramp. This function declares a bitmap shape reference and a bitmap geometry structure using the declarations
  8709. gxShape  aBitmapShape;
  8710. gxBitmap aBitmapGeometry;
  8711. It then fills in the fields of the bitmap geometry structure. First, it fills in the dimensions:
  8712. aBitmapGeometry.width = 1;
  8713. aBitmapGeometry.height = 256;
  8714. aBitmapGeometry.pixelSize = 32;
  8715. Notice that the sample function defines the bitmap width to be 1. Later, the sample function uses the GXSetShapeBounds function later to widen the bitmap.
  8716. Next, the sample function sets the image field to nil to indicate that QuickDraw GX should allocate memory for the pixel image of the bitmap. The value of the rowBytes field is ignored because QuickDraw GX sets this field when allocating the pixel image.
  8717. The sample function then sets the color-related fields of the bitmap geometry structure:
  8718. aBitmapGeometry.space = gxRgb32Space;
  8719. aBitmapGeometry.set = nil;
  8720. aBitmapGeometry.profile = nil;
  8721. Notice that the pixel size implied by the color space (which is the gxRgb32Space color space) is the same as the pixel size indicated in the pixelSize field of the bitmap geometry structure (which is 32). 
  8722. Next, the sample function creates the bitmap shape:
  8723. aBitmapShape = GXNewBitmap(&aBitmapGeometry, &initialPosition);
  8724. The sample function then sets the color values of each pixel in the bitmap shape. To do this, it creates a color structure with the declaration
  8725. gxColor current;
  8726. and fills in the values of the fields of the color structure:
  8727. current.space = gxRgbSpace;
  8728. current.profile = nil;
  8729. current.element.rgb.red = 0xFFFF;  
  8730. current.element.rgb.green = 0;       
  8731. current.element.rgb.blue = 0;      
  8732. current.element.rgb.alpha = 0; 
  8733. (For a complete discussion of these fields, see the chapter “Color and Color-Related Objects” in Inside Macintosh: QuickDraw GX Objects.) 
  8734. The sample function then uses the GXSetShapePixel function to set the each pixel value in the pixel image of the bitmap shape. Each time the sample function sets the value of a pixel, it changes the color value of the current variable slightly, decreasing the amount of green and increasing the amount of red:
  8735. for (count = 0; count < 256; count++) {
  8736.     current.element.component[0] -= 0x0101; /* decrease red */
  8737.     current.element.component[1] += 0x0101; /* increase green */
  8738.         
  8739.     GXSetShapePixel(aBitmapShape, 0, count, ¤t, 0);
  8740. }
  8741. Finally, the sample function resizes the bitmap, widening it to be a square, and draws the resulting bitmap color ramp. The complete sample function definition is shown in Listing 5-4.
  8742. Listing 5-4    Creating a color ramp
  8743.  
  8744. void CreateColorRamp(void)
  8745. {
  8746.     gxShape aBitmapShape;
  8747.     gxBitmap aBitmapGeometry;
  8748.     gxPoint initialLocation = {ff(50), ff(50)};
  8749.     gxRectangle theBounds = {ff(50), ff(50), ff(150), ff(150)};
  8750.     
  8751.     gxColor current;
  8752.     int count;
  8753.     
  8754.     /* create a one-pixel-wide bitmap */
  8755.     aBitmapGeometry.width = 1;
  8756.     aBitmapGeometry.height = 256;
  8757.     aBitmapGeometry.rowBytes = 1;
  8758.     aBitmapGeometry.pixelSize = 32;
  8759.     
  8760.     aBitmapGeometry.image = nil;  /* have QuickDraw GX allocate */
  8761.  
  8762.     aBitmapGeometry.space = gxRgb32Space;
  8763.     aBitmapGeometry.set = nil;
  8764.     aBitmapGeometry.profile = nil;
  8765.  
  8766.     aBitmapShape = GXNewBitmap(&aBitmapGeometry, &initialLocation);
  8767.      
  8768.     /* create a red color */
  8769.     current.space = gxRgbSpace;
  8770.     current.profile = nil;
  8771.     current.element.component[0] = 0xFFFF;  /* red */
  8772.     current.element.component[1] = 0;       /* green */
  8773.     current.element.component[2] = 0;       /* blue */
  8774.     current.element.component[3] = 0;       /* alpha */
  8775.     
  8776.     /*     fill in the colors of the bitmap pixel by pixel */
  8777.     for (count = 0; count < 256; count++) {
  8778.         current.element.rgb.red -= 0x0101;    /* decrease red */
  8779.         current.element.rgb.green += 0x0101; /* increase green */
  8780.         
  8781.         GXSetShapePixel(aBitmapShape, 0, count, ¤t, 0);
  8782.     }
  8783.  
  8784.     /* resize the bitmap to give it more width */
  8785.     GXSetShapeBounds(aBitmapShape, &theBounds);
  8786.     
  8787.     GXDrawShape(aBitmapShape);
  8788.     GXDisposeShape(aBitmapShape);
  8789. }
  8790. The resulting color ramp is shown in Figure 5-14. For a color version of this figure, see Plate 3 at the front of this book.
  8791. Figure 5-14    A color ramp from red to green
  8792.  
  8793. QuickDraw GX provides the ramp library to assist you in creating color ramps. The NewRamp library function requires you to provide a start color, an end color, an integer indicating the number of different colors to calculate in between the start color and end color, and a bounding rectangle for the final color ramp. Listing 5-5 shows how to use this function to create the same color ramp shown in Figure 5-14.
  8794. Listing 5-5    Creating a color ramp using the ramp library
  8795.  
  8796. void CreateColorRamp(void)
  8797. {
  8798.     gxShape aBitmapShape;
  8799.     gxColor start, end;
  8800.     const gxRectangle theBounds = {ff(50), ff(50), 
  8801.                                              ff(150), ff(150)};
  8802.  
  8803.     start.space = gxRgbSpace;
  8804.     start.profile = nil;
  8805.     start.element.rgb.red = 0xFFFF;               
  8806.     start.element.rgb.green = 0; 
  8807.     start.element.rgb.blue = 0;       
  8808.     start.element.rgb.alpha = 0;         
  8809.  
  8810.     end.space = gxRgbSpace;
  8811.     end.profile = nil;
  8812.     end.element.rgb.red = 0;               
  8813.     end.element.rgb.green = 0xFFFF;  
  8814.     end.element.rgb.blue = 0;     
  8815.     end.element.rgb.alpha = 0;         
  8816.  
  8817.     aBitmapShape = NewRamp(&start, &end, 256, &theBounds);
  8818.     GXDrawShape(aBitmapShape);
  8819.     GXDisposeShape(aBitmapShape);
  8820. }
  8821. As a further convenience, QuickDraw GX provides the color library, which allows you to use predefined constants to specify frequently-used colors. You provide the SetCommonColor library function with
  8822. n    a pointer to a color structure,
  8823. n    a predefined constant specifying the color you want
  8824. This function then initializes the color structure with the appropriate values to represent the color you specify.
  8825. For example,
  8826. SetCommonColor(&start, red);
  8827. sets the fields of the start color structure with the values that represent the color red.
  8828. Listing 5-6 shows you how to create the color ramp in Figure 5-14 by using functions from both the ramp and common color libraries.
  8829. Listing 5-6    Creating a color ramp using both the ramp and color libraries
  8830.  
  8831. void CreateColorRamp(void)
  8832. {
  8833.     gxShape  aBitmapShape;
  8834.     gxColor start, end;
  8835.     const gxRectangle theBounds = {ff(50), ff(50), 
  8836.                                              ff(150), ff(150)};
  8837.  
  8838.     SetCommonColor(&start, red);
  8839.     SetCommonColor(&end, green);
  8840.  
  8841.     aBitmapShape = NewRamp(&start, &end, 0, &theBounds);
  8842.     GXDrawShape(aBitmapShape);
  8843.     GXDisposeShape(aBitmapShape);
  8844. }
  8845. For a discussion of pixel images and bitmap geometries, see “Bitmap Geometries” beginning on page 5-4.
  8846. You can find more information about colors, color structures, color values, color sets, and color spaces in the chapter “Colors and Color-Related Objects” in Inside Macintosh: QuickDraw GX Objects.
  8847. Dithering and Halftoning Bitmaps
  8848.  
  8849. The color ramp created in the previous section uses the gxRgb32Space color space, but not all display devices can display 32 bits of color. To optimize the appearance of color on displays with limited numbers of colors, QuickDraw GX allows you to dither shapes—that is, approximate colors that a display device cannot draw with patterns of similar colors that the display device can draw.
  8850. The chapter “View-Related Objects” in Inside Macintosh: QuickDraw GX Objects describes dithering in detail. 
  8851. This section shows how you can use dithering to draw the color ramp shown in Figure 5-15 on page 5-29.
  8852. Since dithering is a function of view port objects, you must first determine the view port to which the color ramp is drawn. Since this color ramp is only being drawn to one view port, you can declare an array to hold a single view port reference
  8853. gxViewPort aViewPortList[1];
  8854. and then use the GXGetShapeGlobalViewPorts function to copy the view port list from the color ramp bitmap shape’s transform object into the view port array:
  8855. GXGetShapeGlobalViewPorts(aColorRampBitmapShape, aViewPortList);
  8856. If the color ramp were being drawn to multiple view ports, you would call this function once specifying nil for the view port array to determine the number of view ports, then allocate space to hold the view port references, and then call the function a second time to determine the actual view port references.
  8857. In the color ramp example, you can use the GXSetViewPortDither function to indicate that shapes drawn to this view port should be dithered. This function takes two parameters: a reference to the view port and a dither level, which is described in detail in the “View-Related Objects” chapter of Inside Macintosh: QuickDraw GX Objects. If a view port has a dither level of 2 or greater, QuickDraw GX dithers bitmaps drawn to that view port:
  8858. GXSetViewPortDither(aViewPortList[0], 4); /* Dither bitmaps */
  8859. Figure 5-15 shows how QuickDraw GX draws the dithered color ramp to display devices at two different pixel depths.
  8860. Figure 5-15    Dithered bitmaps
  8861.  
  8862. Halftoning, which is also described in the chapter “View-Related Objects” in Inside Macintosh: QuickDraw GX Objects, is similar to dithering. To specify halftoning for a view port, you need to create a gxHalftone structure. This structure specifies information about how QuickDraw GX should halftone shapes drawn to the view port. Listing 5-7 shows how to create a sample gxHalftone structure and set the halftone characteristics for the view port of color ramp bitmap.
  8863. Listing 5-7    Halftoning a bitmap
  8864.  
  8865. gxHalftone aHalfTone;
  8866.  
  8867. SetCommonColor(&halftoneDots, gxBlack);
  8868. SetCommonColor(&halftoneBackground, gxWhite);
  8869.  
  8870. aHalftone.angle = ff(45);
  8871. aHalftone.frequency = ff(5);
  8872. aHalftone.method = gxRoundDot;
  8873. aHalftone.tinting = gxComponent1Tint;
  8874. aHalftone.dotColor = halftoneDots;
  8875. aHalftone.backgroundColor = halftoneBackground;
  8876. aHalftone.tintSpace = gxRgbSpace;
  8877.  
  8878. GXGetShapeGlobalViewPorts(aBitmapShape, aViewPort);
  8879. GXSetViewPortHalftone(aViewPort[0], &aHalftone);
  8880. Figure 5-16 shows three possible results of halftoning the color ramp bitmap. The first example is the result of Listing 5-7—round dots and a dot frequency of 5. The other two examples show the result of halftoning the color ramp bitmap with other dot frequencies and dot shapes.
  8881. Figure 5-16    Halftoned bitmaps
  8882.  
  8883. Applying Transfer Modes to Bitmaps
  8884.  
  8885. When drawing a bitmap, QuickDraw GX uses the color information stored in the geometry of the bitmap shape; it ignores the color information stored in the ink object associated with the bitmap shape.
  8886. However, QuickDraw GX does consider the transfer mode information specified in a bitmap shape’s ink object. QuickDraw GX uses the transfer mode when drawing each pixel of a bitmap.
  8887. As an example, the sample function in Listing 5-8 creates a rectangle shape containing a purple rectangle and a bitmap shape containing a color ramp from red to green (as described in Listing 5-6 on page 5-27). 
  8888. Listing 5-8    Applying a transfer mode to a bitmap
  8889.  
  8890. void ApplyTransferModeToBitmap(void)
  8891. {
  8892.     gxShape aRectangleShape, aBitmapShape;
  8893.     gxRectangle theRectangleBounds = {ff(100), ff(100), 
  8894.                                                 ff(200), ff(200)};
  8895.  
  8896.     gxRectangle theBitmapBounds = {ff(50), ff(50), 
  8897.                                             ff(150), ff(150)};
  8898.  
  8899.     gxColor start, end;
  8900.  
  8901.  
  8902.     aRectangleShape = GXNewRectangle(&theRectangleBounds);
  8903.     SetShapeCommonColor(aRectangleShape, purple);
  8904.  
  8905.     SetCommonColor(&start, red);
  8906.     SetCommonColor(&end, green);
  8907.     aBitmapShape = NewRamp(&start, &end, 0, &theBitmapBounds);
  8908.     SetShapeCommonTransfer(aBitmapShape, gxBlendMode);
  8909.  
  8910.     GXDrawShape(aRectangleShape);
  8911.     GXDrawShape(aBitmapShape);
  8912.  
  8913.     GXDisposeShape(aRectangleShape);
  8914.     GXDisposeShape(aBitmapShape);
  8915. }
  8916. The sample function then uses the transfer mode library function SetShapeCommonTransfer to set the transfer mode of the bitmap shape to gxBlendMode.
  8917. Finally, the sample function draws the purple rectangle and the bitmap. Since the ink object associated with the bitmap specifies the gxBlendMode common transfer mode, QuickDraw GX applies this transfer mode when drawing each pixel of the bitmap. Pixels that fall over the white background are blended with white, and pixels that fall over the purple rectangle are blended with purple.
  8918. Figure 5-17 shows the result of this sample function. For a color version of this figure, see Plate 3 at the front of this book.
  8919. Figure 5-17    A blended color ramp
  8920.  
  8921. You can find more information about transfer modes in the “Ink Objects” chapter of Inside Macintosh: QuickDraw GX Objects.
  8922. Converting Other Types of Shapes to Bitmaps
  8923.  
  8924. The examples in the previous sections show you how to create a bitmap shape by specifying the value of every pixel in the pixel image yourself. You can also create bitmaps using one of a number of simpler methods. For example, you can convert any QuickDraw GX shape to a bitmap shape. The pixel image of the resulting bitmap shape contains a bitmap representation of the original shape. (In a similar way, when you draw a shape to a display device, the display device displays a bitmap representation of the original shape.)
  8925. To convert another type of shape into a bitmap shape, you use the GXSetShapeType function, which is described in detail in the chapter “Shape Objects” of Inside Macintosh: QuickDraw GX Objects.
  8926. Listing 5-9 shows a sample function that defines a figure-eight geometry, encapsulates the geometry in a path shape, sets the pen width of that path to 10, and skews the path around its center by 10% along both the horizontal and vertical axes. Then the sample function converts the path shape into a bitmap shape and draws the bitmap.
  8927. Listing 5-9    Converting a path to a bitmap
  8928.  
  8929. void ConvertPathToBitmap(void)
  8930. {
  8931.     gxShape pathToBitmapShape;
  8932.  
  8933.     gxRectangle theBounds;
  8934.     
  8935.     const long figureEightGeometry[] = {1,
  8936.                                                  4,
  8937.                                                  0xF0000000,
  8938.                                                  ff(20), ff(20),   /* off */
  8939.                                                  ff(100), ff(100), /* off */
  8940.                                                  ff(20), ff(100),  /* off */
  8941.                                                  ff(100), ff(20)}; /* off */
  8942.                                         
  8943.     pathToBitmapShape = GXNewPaths((gxPaths *)     figureEightGeometry);
  8944.     GXSetShapeFill(pathToBitmapShape, gxClosedFrameFill);
  8945.     GXSetShapePen(pathToBitmapShape, ff(10));
  8946.     GXSkewShape(pathToBitmapShape, fl(.1), fl(.1), ff(60), ff(60));
  8947.    
  8948.     GXSetShapeType(pathToBitmapShape, gxBitmapType);
  8949.      GXDrawShape(pathToBitmapShape);
  8950.      GXDisposeShape(pathToBitmapShape);
  8951. }
  8952. Listing 5-9 uses the GXSkewShape function, which is described fully in the chapter “Transform Objects” in Inside Macintosh: QuickDraw GX Objects.
  8953. Figure 5-18 shows the result of this function.
  8954. Figure 5-18    A bitmap representation of a path shape
  8955.  
  8956. Notice that QuickDraw GX draws the bitmap at 72 pixels per inch.
  8957. When converting shapes to bitmap shapes, QuickDraw GX creates a bitmap shape with the smallest pixel image possible to contain the bitmap representation of the original shape. To illustrate, you can draw the bounding rectangle of the skewed figure-eight bitmap by adding to Listing 5-9 the declaration
  8958. gxRectangle theBounds;
  8959. and these two lines of code:
  8960. GXGetShapeBounds(pathToBitmapShape, 0, &theBounds);
  8961. GXDrawRectangle(&theBounds, gxClosedFrameFill);
  8962. The resulting bitmap and bounding rectangle are shown in Figure 5-19.
  8963. Figure 5-19    A bitmap and its bounding rectangle
  8964.  
  8965. When QuickDraw GX converts other types of shapes into a bitmap shapes, it creates a new bitmap geometry and draws the original shape into the bitmap’s pixel image. If the original shape does not cover all of the pixels in the bitmap’s pixel image, QuickDraw GX sets the color value of the extra pixels to white. These white pixels may produce unexpected results if you draw the bitmap over a background that includes colors other than white.
  8966. For example, if you add a background shape to the sample function in Listing 5-9:
  8967. gxShape backgroundShape;
  8968. const gxRectangle backgroundBounds = {ff(20), ff(10), 
  8969.                                                   ff(100), ff(110)};
  8970.  
  8971. backgroundShape = GXNewRectangle(&backgroundBounds);
  8972. SetShapeCommonColor(backgroundShape, purple);
  8973. and draw the background before the bitmap:
  8974. GXDrawShape(backgroundShape);
  8975. GXDrawShape(pathToBitmapShape);
  8976. the result appears as shown in Figure 5-20. (For a color version of this figure, see Plate 4 at the front of this book.)
  8977. Figure 5-20    A bitmap drawn over a background
  8978.  
  8979. As Figure 5-20 shows, the white pixels of the bitmap cover the corresponding area of the blue rectangle. However, you can set the transfer mode of the bitmap shape to allow the blue show through the white pixels. Setting the transfer mode of the bitmap to the gxMinimumMode common transfer mode, 
  8980. SetShapeCommonTransfer(pathToBitmapShape, gxMinimumMode);    
  8981. GXDrawShape(pathToBitmapShape);
  8982. results in the image shown in Figure 5-21. (For a color version of this figure, see Plate 5 at the front of this book.)
  8983. Figure 5-21    A bitmap with a transfer mode drawn over a background
  8984.  
  8985. Another way to allow the blue rectangle to show through the white areas of this bitmap is to set the clip shape of the bitmap. The next section, “Applying Transfer Modes to Bitmaps,” shows an example of clipping a bitmap.
  8986. The examples in this section use common colors and the SetCommonColor library function, which are available in the color library, and common transfer modes and the SetShapeCommonTransfer library function, which are available in the transfer mode library.
  8987. For more information about the GXSetShapeType function, see the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  8988. For information about combining multiple QuickDraw GX shapes to a single bitmap shape, see “Creating Bitmaps Offscreen,” which begins on page 5-42.
  8989. Applying Transformations to Bitmaps
  8990.  
  8991. Although bitmap shapes make limited use of their style and ink objects, they make full use of the their transform objects. The examples in this section show how you can use the transform object of a bitmap to affect the drawing of that bitmap. The first few sample functions illustrate mapping transformations, and the last sample function illustrates clipping.
  8992. Since a bitmap geometry contains a pixel image rather than a geometric description, applying mapping transformations to bitmap shapes does not produce the same quality results as applying mapping transformations to geometric shapes. To use as an example, Figure 5-18 shows the path shape converted to a bitmap in Listing 5-9 on page 5-32.
  8993. Figure 5-22    A  path shape converted to a bitmap shape 
  8994.  
  8995. You can call the GXSkewShape function to undo the skewing of the figure-eight shape:
  8996. GXSkewShape(pathToBitmapShape, -fl(.1), -fl(.1), ff(60), ff(60));
  8997. Figure 5-23 shows the results of performing this transformation on the figure-eight shape.
  8998. Figure 5-23    A path shape converted to a bitmap shape and then skewed
  8999.  
  9000. As Figure 5-23 shows, the quality of the transformed bitmap has degraded due to the skewing. If the gxMapTransformShape shape attribute of the bitmap shape is not set, this degradation of quality becomes more pronounced with multiple transformations. For example, consider the color ramp depicted in Figure 5-24. For a color version of this figure, see Plate 6 at the front of this book. 
  9001. Figure 5-24    A color ramp bitmap
  9002.  
  9003. If you use 
  9004. GXSetShapeAttributes(aColorRampBitmapShape,
  9005.                           GXGetShapeAttributes(aColorRampBitmapShape) 
  9006.                             & ~gxMapTransformShape);
  9007. to clear the gxMapTransformShape shape attribute for this bitmap shape and then use 
  9008. for (count = 1; count <= 360; count ++)
  9009.     GXRotateShape(aColorRampBitmapShape, ff(1), ff(100), ff(100));
  9010. to rotate the shape 360 times by 1 degree each time, enough error is introduced to create a interesting new bitmap, as shown in Figure 5-25. For a color version of this figure, see plate 7 at the front of this book.
  9011. Figure 5-25    A bitmap after multiple transformations
  9012.  
  9013. However, if you leave the gxMapTransformShape shape attribute set, you can apply the same 360 transformations, and the resulting bitmap is identical to the original bitmap. In this case, all of the transformations affect the mapping matrix stored in the bitmap’s transform object and not the pixel values of the bitmap’s pixel image.
  9014. Scaling text provides another example of transformations degrading the quality with which QuickDraw GX draws a shape. As an example, the sample function in Listing 5-10 creates a text shape, draws it, scales it up, and then draws the scaled version. This sample function uses the GXScaleShape function, which is described in the chapter “Transform Objects” of Inside Macintosh: QuickDraw GX Objects.
  9015. Listing 5-10    Scaling text
  9016.  
  9017. void ScaleText(void)
  9018. {
  9019.     gxShape  aTextShape;
  9020.     gxPoint initialLocation = {ff(50), ff(50)};
  9021.  
  9022.  
  9023.    aTextShape = GXNewText(9, (unsigned char *) "123456789",
  9024.                                   &initialLocation) ;
  9025.     GXDrawShape(aTextShape);
  9026.  
  9027.     GXScaleShape(aTextShape, ff(3), ff(3), ff(0), ff(50));
  9028.  
  9029.     GXDrawShape(aTextShape);
  9030.     GXDisposeShape(aTextShape);
  9031. }
  9032. The result is shown in Figure 5-26.
  9033. Figure 5-26    Scaled text
  9034.  
  9035. If you convert the text shape to a bitmap shape before scaling it, as in the sample function in Listing 5-11, the result is quite different.
  9036. Listing 5-11    Scaling a bitmap
  9037.  
  9038. void ScalingABitmap(void)
  9039. {
  9040.     gxShape aBitmapShape;
  9041.     gxPoint initialLocation = {ff(50), ff(50)};
  9042.  
  9043.  
  9044.    aBitmapShape = GXNewText(9, (unsigned char *) "123456789",
  9045.                                     &initialLocation) ;
  9046.  
  9047.     GXSetShapeType(aBitmapShape, gxBitmapType);
  9048.  
  9049.     GXDrawShape(aBitmapShape);
  9050.  
  9051.     GXScaleShape(aBitmapShape, ff(3), ff(3), ff(0), ff(50));
  9052.  
  9053.     GXDrawShape(aBitmapShape);
  9054.     GXDisposeShape(aBitmapShape);
  9055. }
  9056. Figure 5-27 compares the result of scaling the text shape with the result of scaling the bitmap shape.
  9057. Figure 5-27    Scaled text and a scaled bitmap
  9058.  
  9059. When scaling the text, QuickDraw GX uses the outline information in the font to draw the best representation of the text at the appropriate size. When scaling the bitmap representation of the text, QuickDraw GX simply scales the bits used to represent the smaller version of the text.
  9060. For more information about text shapes, see Inside Macintosh: QuickDraw GX Typography.
  9061. You can also use the transform object of a bitmap shape to clip the bitmap—that is, restrict the area where QuickDraw GX draws the bitmap.
  9062. As an example, to apply a circular clip to the color ramp from Figure 5-24 on page 5-37, you define the circular geometry using the definition
  9063. long theClipGeometry[] = {1, 4, 0xFFFF0000, 
  9064.                                   ff(50), ff(50),
  9065.                                   ff(150), ff(50), 
  9066.                                   ff(150), ff(150),
  9067.                                   ff(50), ff(150)};
  9068. encapsulate it in a path shape with the call
  9069. aClipShape = GXNewPaths((gxPaths *) theClipGeometry);
  9070. and set the clip property of the bitmap’s transform object by using this call to the GXSetShapeClip function:
  9071. GXSetShapeClip(aColorRampBitmapShape, aClipShape);
  9072. QuickDraw GX draws the resulting bitmap shape as shown in Figure 5-28. For a color version of this figure, see Plate 8 at the front of this book.
  9073. Figure 5-28    A clipped bitmap
  9074.  
  9075. For more information about transform objects, mapping transformations, clip shapes, and the GXSetShapeClip function, see the “Transform Objects” chapter of Inside Macintosh: QuickDraw GX Objects.
  9076. Creating Bitmaps With Disk-Based Pixel Images
  9077.  
  9078. QuickDraw GX allows you to store the pixel image of a bitmap shapes in a disk file. To create this type of bitmap, you specify a predefined constant for the image field of the bitmap’s geometry:
  9079. aBitmapGeometry.image = gxBitmapFileAliasImageValue;
  9080. The other fields of the geometry you can initialize as you would for other bitmaps:
  9081. aBitmapGeometry.width = widthOfDiskBasedImage;
  9082. aBitmapGeometry.height = heightOfDiskBasedImage;
  9083. aBitmapGeometry.rowBytes = rowBytesOfDiskBasedImage;
  9084. aBitmapGeometry.pixelSize = pixelSizeOfDiskBasedImage;
  9085.  
  9086. aBitmapGeometry.space = colorSpaceOfDiskBasedImage;
  9087. aBitmapGeometry.set = colorSetOfDiskBasedImage;
  9088. aBitmapGeometry.profile = colorProfileOfDiskBasedImage;
  9089. and you still create the bitmap using the GXNewBitmap function:
  9090. aBitmapShape = GXNewBitmap(&aBitmapGeometry, &initialLocation);
  9091. You specify the file that contains the pixel image using the bitmap data source alias structure, which is defined by the gxBitmapDataSourceAlias data type:
  9092. struct gxBitmapDataSourceAlias {
  9093.     unsigned long             fileOffset;                     /* offset (in bytes) to image */
  9094.     unsigned long             aliasRecordSize;                             /* size of alias record */
  9095.     unsigned char             aliasRecord[gxAnyNumber];     /* alias record */
  9096. };
  9097. To use this data type, you need to declare a variable to hold the structure:
  9098. gxBtimapDataSourceAlias anAlias;
  9099. Then, you need to set the three fields of the structure:
  9100. n    the aliasRecord field should contain a Macintosh Alias Manager alias record specifying the file containing the pixel image
  9101. n    the aliasRecordSize field should specify the size in bytes of of the alias record
  9102. n    the fileOffset field should specify the offset in bytes from the beginning of the file to the first pixel value of the pixel image
  9103. Once you’ve created the bitmap data source alias structure, you create a tag to encapsulate the structure, using the call
  9104. anAliasTag = GXNewTag(gxBitmapFileAliasTagType, sizeOf(anAlias)
  9105.                              &anAlias);
  9106. Then you associate the tag with the bitmap shape using the call
  9107. GXSetShapeTags(aBitmapShape, gxBitmapFileAliasTagType, 
  9108.                     1,  /* first tag */
  9109.                     –1, /* replace all tags of same type */
  9110.                     1,  /* insert one new tag */
  9111.                     &anAliasTag); /* tag to insert */
  9112. Now the disk-based bitmap is completely initialized. You can use most bitmap-related functions with this bitmap, but there are bitmap-related functions you cannot use. In particular, you cannot call the GXSetBitmapParts, GXSetShapePixel, GXNewViewDevice, or GXSetViewDeviceBitmap functions, as these functions would require QuickDraw GX to write to the file.
  9113. For more information about alias records, see the chapter “Alias Manager” of Inside Macintosh: Files.
  9114. For more information about tags and the GXNewTag function, see the chapter “Tag Objects” of Inside Macintosh: QuickDraw GX Objects. For information about the GXSetShapeTags function, see the chapter “Shape Objects” in that book.
  9115. Creating Bitmaps Offscreen
  9116.  
  9117. The section “Converting Other Types of Shapes to Bitmaps” beginning on page 5-32 describes how you can convert a single QuickDraw GX shape to a bitmap shape. This section shows you how to draw multiple QuickDraw GX shapes to a single bitmap shape.
  9118. When you draw a shape, QuickDraw GX does the following:
  9119. n    examines the shape’s transform object, which contains a view port list
  9120. n    examines the view ports in this list, each of which belongs to a view group
  9121. n    examines these view groups, which contain view devices
  9122. n    decides which view devices the shape actually intersects
  9123. n    examines these view devices, each of which contains a bitmap
  9124. n    renders the shape into these bitmaps
  9125. Therefore, to draw shapes into an offscreen bitmap, you need to
  9126. n    create an bitmap shape to contain the rendered shapes
  9127. n    create a view group to contain a view device
  9128. n    create a view device to contain the bitmap shape
  9129. n    create a view port that belongs to the view group
  9130. n    create a transform to reference the view port
  9131. n    associate the transform with the shapes you want to draw offscreen
  9132. n    draw the shapes
  9133. You can find complete information about transforms, view devices, view groups, and view ports in the chapters “Transform Objects” and “View-Related Objects” in Inside Macintosh: QuickDraw GX Objects.
  9134. To create the offscreen bitmap, you must define a shape reference for the bitmap shape, as in the declaration
  9135. gxShape  aBitmapShape;
  9136. and create a bitmap shape of the appropriate size, as with the call
  9137. aBitmapShape = CreateABitmap(200, 200);
  9138. Listing 5-12 shows a possible definition for the CreateABitmap function. This function creates a black-and-white bitmap of a specified height and width.
  9139. Listing 5-12    Creating a black-and-white bitmap that uses QuickDraw GX memory
  9140.  
  9141. static gxShape CreateABitmap(long height, long width)
  9142. {
  9143.     gxShape aBitmapShape;
  9144.     gxBitmap aBitmapGeometry;
  9145.     gxPoint initialLocation = {ff(0), ff(0)};
  9146.  
  9147.     aBitmapGeometry.image = nil;
  9148.  
  9149.     aBitmapGeometry.width = width;
  9150.     aBitmapGeometry.height = height;
  9151.     aBitmapGeometry.rowBytes = 0;
  9152.     aBitmapGeometry.pixelSize = 1;
  9153.  
  9154.     aBitmapGeometry.space = gxNoSpace;
  9155.     aBitmapGeometry.set = nil;
  9156.     aBitmapGeometry.profile = nil;
  9157.  
  9158.     aShape = GXNewBitmap(&aBitmapGeometry, &initialLocation);
  9159.  
  9160.     return(aBitmapShape);
  9161. }
  9162. To create the offscreen view device, view group, and view port objects, you must declare references to them:
  9163. gxViewGroup offscreenViewGroup;
  9164. gxViewDevice offscreenViewDevice;
  9165. gxViewPort offscreenViewPort;
  9166. You create the view group object first:
  9167. offscreenViewGroup = GXNewViewGroup();
  9168. Then you can create the view device and view port objects. To create a view device, you must specify both the view group it belongs to and the bitmap it uses when rendering shapes:
  9169. offscreenViewDevice = GXNewViewDevice(offscreenViewGroup,
  9170.                                                   aBitmapShape);
  9171. To create a view port, you need only specify the view group to which it belongs:
  9172. offscreenViewPort = GXNewViewPort(offscreenViewGroup);
  9173. To draw shapes to this offscreen view port, you need to create a new transform object. First, you must declare a reference to a transform object:
  9174. gxTransform offscreenTransform;
  9175. Then you can create it and set its view port list to contain the offscreen view port:
  9176. offscreenTransform = GXNewTransform();
  9177. GXSetTransformViewPorts(offscreenTransform, 1, 
  9178.                                 &offscreenViewPort);
  9179. Now you’re ready to draw shapes offscreen. The first shape that you draw is a simple white rectangle, and drawing it initializes the pixels in the offscreen bitmap:
  9180. gxShape aRectangleShape;
  9181. gxRectangle boundsRectangle = {ff(0), ff(0), ff(200), ff(200)};
  9182.  
  9183. aRectangleShape = GXNewRectangle(&boundsRectangle);
  9184.  
  9185. SetShapeCommonColor(aRectangleShape, gxWhite);
  9186. To draw this white rectangle to the offscreen bitmap, you must set its transform object to be the offscreen transform object:
  9187. GXSetShapeTransform(aRectangleShape, offscreenTransform);
  9188. Then you draw and dispose of the shape:
  9189. GXDrawShape(aRectangleShape);
  9190. GXDisposeShape(aRectangleShape);
  9191. Since the rectangle shape references the offscreen transform object, QuickDraw GX draws the white rectangle into the offscreen bitmap.
  9192. Because the offscreen bitmap is now initialized, you can draw other shapes to it. The following code demonstrates how to create a line shape and draw it to the offscreen bitmap:
  9193. gxShape aLineShape;
  9194. gxLine lineGeometry = {ff(40), ff(40), ff(160), ff(160)};
  9195. aLineShape = GXNewLine(&lineGeometry);
  9196. GXSetShapePen(aLineShape, ff(50));
  9197. GXSetShapeTransform(aLineShape, offscreenTransform);
  9198. GXDrawShape(aLineShape);
  9199. GXDisposeShape(aLineShape);
  9200. As another example, the following code demonstrates how to create a text shape and draw it to the offscreen bitmap:
  9201. gxShape aTextShape;
  9202. gxPoint textLocation = {ff(70), ff(100)};
  9203. gxPoint textCenter;
  9204. aTextShape = GXNewText(9, (unsigned char *) "123456789",
  9205.                              &textLocation) ;
  9206. GXGetShapeCenter(aTextShape, 0, &textCenter);
  9207. GXScaleShape(aTextShape, ff(3), ff(3), 
  9208.                  textCenter.x, textCenter.y);
  9209. SetShapeCommonTransfer(aTextShape, gxXorMode);
  9210.  
  9211. GXSetShapeTransform(aTextShape, offscreenTransform);
  9212. GXDrawShape(aTextShape);
  9213. GXDisposeShape(aTextShape);
  9214. This code segment uses the SetShapeCommonTransfer library function, which is available in the transfer mode library.
  9215. Finally, to transfer the offscreen bitmap to the screen, you need only draw the bitmap:
  9216. GXDrawShape(aBitmapShape);
  9217. When drawing the offscreen bitmap, QuickDraw GX uses the information in the transform object of the offscreen bitmap shape. This example uses the GXNewBitmap function to create the offscreen bitmap, and so it references the same transform object as the default bitmap shape.  The transform of the default bitmap references the default view port, which you can set using the SetDefaultViewPort function, as described in the chapter “View-Related Objects” in Inside Macintosh: QuickDraw GX Objects. Since the default view port is typically on screen, drawing the offscreen bitmap effectively transfers it to the screen.
  9218. Listing 5-13 shows the complete sample function to create an offscreen bitmap, draw shapes to it, and copy it to the screen.
  9219. Listing 5-13    Creating an offscreen bitmap
  9220.  
  9221. void CreateOffscreenBitmap(void)
  9222. {
  9223.     gxShape  aBitmapShape, aRectangleShape, aLineShape, aTextShape;
  9224.     
  9225.     gxRectangle boundsRectangle = {ff(0), ff(0), ff(200), ff(200)};
  9226.     gxLine lineGeometry = {ff(40), ff(40), ff(160), ff(160)};
  9227.     gxPoint textLocation = {ff(70), ff(100)};
  9228.     gxPoint textCenter;
  9229.     
  9230.     /* declare view group, etc. */
  9231.     
  9232.    aBitmapShape = CreateABitmap(200, 200);
  9233.  
  9234.     offscreenViewGroup = GXNewViewGroup();
  9235.     offscreenViewDevice = GXNewViewDevice(offscreenViewGroup,
  9236.                                                      aBitmapShape);
  9237.     offscreenViewPort = GXNewViewPort(offscreenViewGroup);
  9238.     offscreenTransform = GXNewTransform();
  9239.     GXSetTransformViewPorts(offscreenTransform, 1, 
  9240.                                    &offscreenViewPort);
  9241.  
  9242.     /* draw white rectangle to clear bitmap */
  9243.     aRectangleShape = GXNewRectangle(&boundsRectangle);
  9244.     GXSetShapeTransform(aRectangleShape, offscreenTransform);
  9245.     SetShapeCommonColor(aRectangleShape, gxWhite);
  9246.     GXDrawShape(aRectangleShape);
  9247.     GXDisposeShape(aRectangleShape);
  9248.  
  9249.     /* draw thick diagonal line offscreen */
  9250.     aLineShape = GXNewLine(&lineGeometry);
  9251.     GXSetShapePen(aLineShape, ff(50));
  9252.     GXSetShapeTransform(aLineShape, offscreenTransform);
  9253.     GXDrawShape(aLineShape);
  9254.     GXDisposeShape(aLineShape);
  9255.     
  9256.     /* draw text offscreen */
  9257.     aTextShape = GXNewText(9, (unsigned char *) "123456789",
  9258.                                   &textLocation) ;
  9259.     GXGetShapeCenter(aTextShape, 0, &textCenter);
  9260.     GXScaleShape(aTextShape, ff(3), ff(3), textCenter.x, 
  9261.                     textCenter.y);
  9262.     SetShapeCommonTransfer(aTextShape, gxXorMode);
  9263.  
  9264.     GXSetShapeTransform(aTextShape, offscreenTransform);
  9265.     GXDrawShape(aTextShape);
  9266.     GXDisposeShape(aTextShape);
  9267.     
  9268.     /* transfer bitmap to screen */
  9269.     GXDrawShape(aBitmapShape);
  9270.     GXDisposeShape(aBitmapShape);
  9271.         
  9272.     GXDisposeTransform(offscreenTransform);
  9273.     GXDisposeViewGroup(offscreenViewGroup);    
  9274. }
  9275. Figure 5-29 shows the result of this function.
  9276. Figure 5-29    Multiple shapes drawn to a bitmap
  9277.  
  9278. The offscreen library provided with QuickDraw GX contains some utilities that simplify the creation of offscreen bitmaps. This library defines the offscreen structure, which contains a reference to a transform, view port, view device, and view group. Listing 5-14 shows how to use the offscreen library to create the bitmap shown in Figure 5-29 .
  9279. Listing 5-14    Creating an offscreen bitmap using the offscreen library
  9280.  
  9281. void CreateOffscreenBitmap(void)
  9282. {
  9283.     shape  aBitmapShape, aRectangleShape, aLineShape, aTextShape;
  9284.     
  9285.     offscreen anOffscreen;
  9286.     
  9287.     gxRectangle boundsRectangle = {ff(0), ff(0), ff(200), ff(200)};
  9288.     gxLine lineGeometry = {ff(40), ff(40), ff(160), ff(160)};
  9289.     gxPoint textLocation = {ff(70), ff(100)};
  9290.     gxPoint textCenter;
  9291.     
  9292.    aBitmapShape = CreateABitmap(200, 200);
  9293.  
  9294.     /* create all offscreen-related objects */
  9295.     CreateOffscreen(&anOffscreen, aBitmapShape);
  9296.  
  9297.     aRectangleShape = GXNewRectangle(&boundsRectangle);
  9298.     GXSetShapeTransform(aRectangleShape, anOffscreen.xform);
  9299.     SetShapeCommonColor(aRectangleShape, gxWhite);
  9300.     GXDrawShape(aRectangleShape);
  9301.     GXDisposeShape(aRectangleShape);
  9302.  
  9303.     aLineShape = GXNewLine(&lineGeometry);
  9304.     GXSetShapePen(aLineShape, ff(50));
  9305.     GXSetShapeTransform(aLineShape, anOffscreen.xform);
  9306.     GXDrawShape(aLineShape);
  9307.     GXDisposeShape(aLineShape);
  9308.     
  9309.     aTextShape = GXNewText(9, (unsigned char *) "123456789",
  9310.                                   &textLocation) ;
  9311.     GXGetShapeCenter(aTextShape, 0, &textCenter);
  9312.     GXScaleShape(aTextShape, ff(3), ff(3), textCenter.x,
  9313.                     textCenter.y);
  9314.     SetShapeCommonTransfer(aTextShape, gxXorMode);
  9315.  
  9316.     GXSetShapeTransform(aTextShape, anOffscreen.xform);
  9317.     GXDrawShape(aTextShape);
  9318.     GXDisposeShape(aTextShape);
  9319.     
  9320.     GXDrawShape(aBitmapShape);
  9321.     GXDisposeShape(aBitmapShape);
  9322.  
  9323.     /* dispose all offscreen-related         objects */
  9324.     DisposeOffscreen(&anOffscreen);
  9325.         
  9326.     GXDrawShape(aBitmapShape);
  9327.     GXDisposeShape(aBitmapShape);
  9328. }
  9329. Editing Parts of a Bitmap
  9330.  
  9331. QuickDraw GX provides two functions that allow you to manipulate part of a bitmap. The GXGetBitmapParts function copies a rectangular subsection from one bitmap to a new bitmap, and the GXSetBitmapParts function replaces a rectangular subsection of one bitmap with another bitmap.
  9332. To extract part of a bitmap shape, you need to declare a reference to a new bitmap shape to hold the extracted part:
  9333. gxShape extractedBitmap;
  9334. You also need to specify what part of the bitmap to extract. QuickDraw GX provides the gxLongRectangle sturcture for this purpose:
  9335. gxLongRectangle extractedBounds = {70, 70, 125, 125};
  9336. You can then use the GXGetBitmapParts function to extract the specified section. For example,
  9337. extractedBitmap = GXGetBitmapParts(aBitmapShape, 
  9338.                                               &extractedBounds);
  9339. extracts from the bitmap referenced by the aBitmapShape variable the section starting at 70 pixels over and 70 pixels down and ending at 125 pixels over and 125 pixels down.
  9340. Applying this function call to the bitmap shown in Figure 5-29 results in the bitmap shown in Figure 5-30.
  9341. Figure 5-30    An extracted bitmap
  9342.  
  9343. You can use the GXSetBitmapParts function to replace a section of one bitmap with the contents of another bitmap.
  9344. For example, you might create a small, square bitmap containing all black pixels:
  9345. gxShape insertionBitmap;
  9346. gxRectangle insertionGeometry = {ff(0), ff(0), ff(100), ff(100)};
  9347.  
  9348. insertionBitmap = GXNewRectangle(&insertionGeometry);
  9349. GXSetShapeType(insertionBitmap, gxBitmapType);
  9350. Then you can insert that bitmap into the bitmap from Figure 5-29 by specifying where it should be inserted with the declaration
  9351. gxLongRectangle whereToInsert = {70, 70, 125, 125};
  9352. and then inserting it with this call to the GXSetBitmapParts function:
  9353. GXSetBitmapParts(aBitmapShape, &whereToInsert, insertionBitmap);
  9354. Notice that the insertionBitmap shape is larger than the whereToInsert rectangle. QuickDraw GX only inserts as much of the insertionBitmap shape as fits in the whereToInsert rectangle, starting with the upper-left corner of the insertionBitmap shape. 
  9355. The resulting bitmap is shown in Figure 5-31. (*** This needs final art. ***)
  9356. Figure 5-31    An editied bitmap 
  9357.  
  9358.  
  9359.  
  9360. Applying Functions Described Elsewhere to Bitmap Shapes
  9361.  
  9362. QuickDraw GX provides only a small number of functions that apply exclusively to bitmaps. However, most of the QuickDraw GX functions that apply to other types of shapes can also be applied to bitmap shapes. 
  9363. The next seven sections discuss how functions described elsewhere operate on bitmaps. These sections are:
  9364. n    “Functions That Post Errors or Warnings When Applied to Bitmap Shapes” beginning on page 5-51, which lists functions that you can apply to other types of shapes but not to bitmap shapes
  9365. n    “Shape-Related Functions Applicable to Bitmap Shapes” beginning on page 5-53, which lists functions that operate on bitmap shape objects
  9366. n    “Geometric Operations Applicable to Bitmap Shapes” beginning on page 5-54, which lists the few geometric operation functions that you can apply to bitmap geometries
  9367. n    “Style-Related Functions Applicable to Bitmap Shapes” beginning on page 5-55, which lists the few style-related functions that affect the drawing of bitmaps
  9368. n    “Ink-Related and Color-Related Functions Applicable to Bitmap Shapes” beginning on page 5-55, which lists the functions that manipulate on the transfer mode of a bitmap shape’s ink object
  9369. n    “Transform-Related Functions Applicable to Bitmap Shapes” beginning on page 5-55, which discusses the functions that allow you to map and clip a bitmap as well as set its hit test parameters and its view port list
  9370. n    “View-Related Functions That Can Be Applied to Bitmap Shapes” beginning on page 5-57, which lists the functions that allow you to associate a bitmap shape with a view device object
  9371. Functions That Post Errors or Warnings When Applied to Bitmap Shapes
  9372.  
  9373. Some QuickDraw GX functions that operate on other types of shapes only post an error or a warning if you try to apply them to a bitmap shape.
  9374. For example, the shape-editing functions listed in Table 5-1 operate on the geometric shape types, but not on bitmap shapes. These functions are described in Chapter 2, “Geometric Shapes,”
  9375. Table 5-1    Geometry-related functions that post errors or warnings when applied to bitmaps
  9376. Function name    Error or warning posted    
  9377. GXGetShapeParts    shape_operator_may_not_be_a_bitmap    
  9378. GXSetShapeParts    shape_operator_may_not_be_a_bitmap    
  9379.  in this book.
  9380. Although you cannot apply the functions listed in Table 5-1 to a bitmap shape, you can use the GXGetBitmapParts and GXSetBitmapParts functions to edit sections of a bitmap. These functions are described in “Editing Bitmaps” beginning on page 5-67.
  9381. There are also a number of geometric operations that you cannot apply to bitmap shapes. Table 5-2 lists these functions, which are described in Chapter 4, “Geometric Operations,”
  9382. Table 5-2    Geometric operations that post errors or warnings when applied to bitmaps
  9383. Function name    Error or warning posted    
  9384. GXBreakShape    graphic_type_does_not_contain_points    
  9385. GXContainsShape    shape_operator_may_not_be_a_bitmap    
  9386. GXDifferenceShape    shape_operator_may_not_be_a_bitmap    
  9387. GXExcludeShape    shape_operator_may_not_be_a_bitmap    
  9388. GXGetShapeCenter    illegal_type_for_shape    
  9389. GXGetShapeDirection    graphic_type_does_not_have_multiple_contours    
  9390. GXGetShapeLength    shape_does_not_have_length    
  9391. GXInsetShape    graphic_type_cannot_be_inset    
  9392. GXIntersectShape    shape_operator_may_not_be_a_bitmap    
  9393. GXInvertShape    shape_cannot_be_inverted    
  9394. GXReverseDifferenceShape    shape_operator_may_not_be_a_bitmap    
  9395. GXReverseShape    contour_out_of_range    
  9396. GXShapeLengthToPoint    shape_does_not_have_length    
  9397. GXTouchesShape    shape_operator_may_not_be_a_bitmap    
  9398. GXUnionShape    shape_operator_may_not_be_a_bitmap    
  9399.  in this book.
  9400. Most of these geometric operations do not apply to bitmap shapes because the geometry of a bitmap is substantially different from the geometry of a geometric shape. 
  9401. You can apply a few of the geometric operations to bitmaps, however. These functions are discussed in “Geometric Operations Applicable to Bitmap Shapes” beginning on page 5-54.
  9402. Shape-Related Functions Applicable to Bitmap Shapes
  9403.  
  9404. You can apply all of the functions described in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects to bitmap shapes. These functions allow you to:
  9405. n    manipulate the shape object that represents the bitmap shape (For example, you can copy, clone, cache, compare, and dispose of the bitmap shape.)
  9406. n    set the geometry, shape type, shape fill, and shape attributes of the bitmap shape
  9407. n    change the style, ink, and transform objects that are associated with the bitmap shape
  9408. n    manipulate the tags and owner count of the bitmap shape
  9409. Table 5-3 gives important bitmap-related information for a subset of the functions from the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects. Functions described in that chapter that do not appear in this list exhibit the same behavior when applied to bitmap shapes as they do when applied to other types of shapes.
  9410. Table 5-3    Shape-related functions that exhibit special behavior when applied to bitmaps
  9411. Function name    Action taken    
  9412. GXChangedShape    Notifies QuickDraw GX that you have directly edited the geometry of the bitmap (using the GXGetShapeStructure and GXLockShape functions). You should call this function when you directly edit any field of a bitmap geometry structure or when you edit the pixel values of a bitmap’s pixel image.    
  9413. GXCopyToShape    Makes a copy of the bitmap shape, but does not copy the pixel image. Instead, the new bitmap shape references the same pixel image.    
  9414. GXCopyDeepToShape    Makes a copy of the bitmap shape, including a complete copy of the bitmap’s pixel image. The copy of the pixel image is allocated in QuickDraw GX memory, regardless of where the original image was allocated.    
  9415. GXEqualShape    Determines if two bitmap shapes are equal—that is, their bitmap position, height, width, color space, color set, and color profile fields are equal, and their pixel images contain the same pixel values.    
  9416. GXGetShapeSize    Determines the amount of memory currently used by the bitmap shape, including the amount of QuickDraw GX memory currently used by the pixel image of the bitmap.    
  9417. GXGetDefaultShape    Returns a reference to the default bitmap shape. The default bitmap shape has 1 bit per pixel, 0 width, and 0 height.    
  9418. GXGetShapeFill    Returns the shape fill of the shape. The shape fill for bitmap shapes is always even-odd (solid) fill or no fill.    
  9419. GXGetShapeStructure    Returns a pointer to the geometry of the bitmap shape. You can use this function to determine the address of the pixel image, even if it is allocated in QuickDraw GX memory.     
  9420. GXLockShape    Loads the bitmap shape into memory and locks its geometry into a fixed memory location. If the pixel image is allocated in QuickDraw GX memory, it is loaded and locked as well.    
  9421. GXNewShape    Creates a bitmap shape with 0 width, 0 height, 32 bits per pixel and rgb32space color space.    
  9422. GXSetShapeFill    Sets the shape fill of the shape. You must always set the shape fill of a bitmap shape to even-odd (solid) fill or no fill.    
  9423. GXSetShapeType    Changes the shape type of the bitmap shape and converts the shape fill and geometry as appropriate.     
  9424.  
  9425. Geometric Operations Applicable to Bitmap Shapes
  9426.  
  9427. Most geometric operations post errors or warnings when applied to bitmap shapes, as described in “Functions That Post Errors or Warnings When Applied to Bitmap Shapes” on page 5-51.
  9428. You can, however, apply the remainder of the functions described in Chapter 4, “Geometric Operations,” to bitmap shapes. Table 5-4 gives important bitmap-related information for a subset of these functions. The remainder of the geometric operations exhibit the same behavior when applied to bitmap shapes as they do when applied to other types of shapes.
  9429. Table 5-4    Geometric operations that exhibit special behavior when applied to bitmaps
  9430. Function name    Action taken    
  9431. GXGetShapeArea    Returns bitmap width multiplied by bitmap height.    
  9432. GXPrimitiveShape    Applies sourceGridStyle attribute to bitmap position.    
  9433. GXSimplifyShape    Reduces the pixel size of the bitmap if the bitmap uses a limited number of colors.    
  9434. GXSetShapeBounds    If the gxMapTransformShape shape attribute is set, this function changes the transform mapping of the bitmap; otherwise, it changes the bitmap height, width, and location, and creates a new, scaled version of the bit image to fit in the new bounding rectangle.    
  9435.  
  9436. Style-Related Functions Applicable to Bitmap Shapes
  9437.  
  9438. As discussed in “Bitmap Styles and Inks” on page 5-7, bitmap shapes make limited use of their style objects. Although you can apply to a bitmap shape any of the functions described in Chapter 3, “Geometric Styles,” only the GXSetShapeStyleAttributes function affects the drawing of the bitmap. While you can use this function to set or clear any of a bitmap’s style attributes, QuickDraw GX considers only the gxSourceGridStyle style attribute and the gxDeviceGridStyle style attribute when drawing bitmaps; other attributes are ignored. 
  9439. You may use the other style-related functions (such as GXSetShapePen, GXSetShapeDash, and so on) to set the other properties of a bitmap’s style object, and you may use the corresponding functions (GXGetShapePen, GXGetShapeDash, and so on) to examine these properties. However, QuickDraw GX ignores these properties when drawing a bitmap.
  9440. Ink-Related and Color-Related Functions Applicable to Bitmap Shapes
  9441.  
  9442. Since bitmap shapes contain their own color information in their geometries, QuickDraw GX does not use the color property of the ink object when drawing a bitmap. However, QuickDraw GX does consider the transfer mode of the ink object and applies it to each pixel when drawing a bitmap. You can use the GXSetShapeTransfer function, which is described in the chapter “Ink Objects” in Inside Macintosh: QuickDraw GX Objects, to assign a transfer mode to a bitmap shape.
  9443. You may also use the GXSetShapeColor function to set the color property of a bitmap’s ink object and use the GXGetShapeColor function to examine this property. However, QuickDraw GX ignores this property when drawing a bitmap.
  9444. Transform-Related Functions Applicable to Bitmap Shapes
  9445.  
  9446. Although bitmap shapes do not make full use of their style and ink objects, they do make full use of their transform objects. You can apply all of the transform-related functions, which are described in the chapter “Transform Objects” in Inside Macintosh: QuickDraw GX Objects, to bitmap shapes. 
  9447. Table 5-5 gives important bitmap-related information for a subset of the functions from that chapter. Functions described in that chapter that do not appear in this list exhibit the same behavior when applied to bitmap shapes as they do when applied to other types of shapes.
  9448. Table 5-5    Transform-related functions that exhibit special behavior when applied to bitmaps
  9449. Function name    Action taken    
  9450. GXGetShapeHitTest    Returns the hit-test parameters associated with the bitmap shape’s transform. QuickDraw GX only hit-tests bitmaps using the boundsPart shape part.    
  9451. GXMapShape    Changes the mapping associated with the transform object of the bitmap shape (if the gxMapTransformShape shape attribute of the bitmap shape is set) or applies the mapping directly to the geometry of the bitmap (if the gxMapTransformShape attribute is not set). Depending on the mapping, this function may also change the clip shape of the bitmap.     
  9452. GXMoveShape    Moves the bitmap by a specified distance. This function can affect the mapping of the bitmap’s transform or the geometry of the bitmap itself, depending on the value of the gxMapTransformShape shape attribute of the bitmap shape.     
  9453. GXMoveShapeTo    Moves the bitmap to a specified position. This function can affect the mapping of the bitmap’s transform or the geometry of the bitmap itself, depending on the value of the gxMapTransformShape shape attribute of the bitmap shape.     
  9454. GXRotateShape    Rotates the bitmap. This function can affect the mapping of the bitmap’s transform or the geometry of the bitmap itself, depending on the value of the gxMapTransformShape shape attribute of the bitmap shape. This function can also affect the clip shape of the bitmap.     
  9455. GXScaleShape    Scales the bitmap. This function can affect the mapping of the bitmap’s transform or the geometry of the bitmap itself, depending on the value of the gxMapTransformShape shape attribute of the bitmap shape. This function can also affect the clip shape of the bitmap.     
  9456. GXSkewShape    Skews the bitmap. This function can affect the mapping of the bitmap’s transform or the geometry of the bitmap itself, depending on the value of the gxMapTransformShape shape attribute of the bitmap shape. This function can also affect the clip shape of the bitmap.     
  9457. GXSetShapeClip    Assigns a clip shape to the transform object associated with the bitmap shape.    
  9458. GXSetShapeHitTest    Assigns hit-test parameters to the transform object associated with the bitmap shape. QuickDraw GX only hit-tests bitmaps using the boundsPart shape part.    
  9459. GXSetShapeMapping    Changes the mapping associated with the transform object of the bitmap shape (if the gxMapTransformShape shape attribute of the bitmap shape is set) or applies the mapping directly to the geometry of the bitmap (if the gxMapTransformShape attribute is not set). Depending on the mapping, this function may also change the clip shape of the bitmap.     
  9460.  
  9461. View-Related Functions That Can Be Applied to Bitmap Shapes
  9462.  
  9463. As described in “Bitmaps and View Devices” beginning on page 5-10, view device objects use bitmaps to store rendered shape images. Table 5-6 lists the function that allows you to determine the bitmap assigned to a view device and the function that allows you to change the bitmap of a view device. Both of these functions are described in detail in the “View-Related Objects” chapter of Inside Macintosh: QuickDraw GX Objects.
  9464. Table 5-6    View-related functions that can be applied to bitmaps
  9465. Function name    Action taken    
  9466. GXGetViewDeviceBitmap    Returns the bitmap shape associated with a view device object.    
  9467. GXSetViewDeviceBitmap    Assigns a bitmap shape to a view device. You can use this function to create offscreen bitmaps, which are discussed in “Bitmaps and View Devices” beginning on page 5-10.    
  9468.  
  9469.  
  9470.  
  9471. Bitmap Shapes Reference
  9472.  
  9473. QuickDraw GX provides four main categories of shapes: geometric shapes, typographic shapes, bitmap shapes, and picture shapes. This section describes the data types and functions you use to manipulate bitmap shapes.
  9474. This reference is divided into two sections:
  9475. n    “Data Types,” beginning on this page, shows the definitions of the data types related to bitmap shapes.
  9476. n    “Functions,” beginning on page 5-61, gives a complete reference for the functions specific to bitmaps.
  9477. In addition to the functions described in the section “Functions,” you can apply many functions described elsewhere to bitmap shapes. See the section “Applying Functions Described Elsewhere to Bitmap Shapes,” which begins on page 5-51, for more details.
  9478. Data Types
  9479.  
  9480. This section describes the data structures you use to create and manipulate bitmaps. 
  9481. You use the gxBitmap structure to specify information about a bitmap geometry and information about how QuickDraw GX should create a bitmap shape. You also use this data structure to specify color information for bitmaps. A complete discussion of the QuickDraw GX color architecture appears in the “Color Objects” chapter of Inside Macintosh: QuickDraw GX Objects.
  9482. You use the gxLongRectangle structure to specify a rectangular subsection of a bitmap pixel image when editing bitmap parts.
  9483. The Bitmap Geometry Structure
  9484.  
  9485. The gxBitmap structure specifies the geometry of a bitmap shape. You can use this data structure when creating bitmap shapes with the GXNewBitmap function, when altering bitmap shapes with the GXGetBitmap and GXSetBitmap functions, and when directly editing bitmap shapes with the GXGetShapeStructure function.
  9486. The gxBitmap structure is defined as:
  9487.     typedef struct {
  9488.         char                 *image;
  9489.         long                 width;        
  9490.         long                 height;
  9491.         long                 rowBytes;    
  9492.         long                 pixelSize;        
  9493.         gxColorSpace                 space;
  9494.         gxColorSet                 set;
  9495.         gxColorProfile                 profile;
  9496.     } gxBitmap;
  9497. Field descriptions
  9498. image    A pointer to the pixel image. When creating a bitmap, you can specify nil for this field to indicate that QuickDraw GX should allocate memory for the pixel image of the bitmap.
  9499. width    The width of the bitmap in pixels.
  9500. height    The height of the bitmap in pixels.
  9501. rowBytes    The number of bytes of the pixel image corresponding to each row of the bitmap. This value must be a positive even number. 
  9502. pixelSize    The number of bits representing a single pixelin the pixel image. This value must be 1, 2, 4, 8, 16, or 32.
  9503. space    The color space that QuickDraw GX uses when interpreting the pixel values in the pixel image. When creating a bitmap, you may specify the gxNoSpace constant for this field to indicate that QuickDraw GX should choose a color space for you. If the value of the pixelSize field is 32, QuickDraw GX uses gxRgb32Space; if the pixel size is 16, QuickDraw GX uses gxRgb16Space; if the pixel size is 8 or less, QuickDraw GX uses gxIndexedSpace and creates a grayscale color set.
  9504. set    The color set that QuickDraw GX uses when interpreting the pixel values of the pixel image. If the space field contains the value gxIndexedSpace, QuickDraw GX interprets the pixel values in the pixel image as indexes to this color set. If the bitmap’s color space is not gxIndexedSpace, this field should be nil. 
  9505. profile    The color matching information about the device on which the bitmap was created. You may provide a reference to a color profile object, or you may set the value of this field to nil.
  9506. Implementation Note
  9507. Version 1.0 of QuickDraw GX limits the bitmap width and the bitmap height to 32767.u
  9508. When creating a bitmap, you can allocate the memory for the pixel image of the bitmap yourself and store a pointer to it in the image field, or you can set the image field to nil, which indicates that QuickDraw GX should allocate the pixel image memory. 
  9509. If you create the pixel image for a bitmap, you must pad the end of each row of the pixel image so that each row contains an even number of bytes. You must store the number of bytes per row in the rowBytes field.
  9510. If you set the image field to nil when creating a bitmap, QuickDraw GX does two things:
  9511. n    creates an uninitialized pixel image based on the bitmap width and height you specify in the width and height fields and the pixel size you specify in the pixelSize field
  9512. n    determines an appropriate rowBytes value
  9513. If you want to create a bitmap with a disk-based pixel image, you should specify the gxBitmapFileAliasImageValue constant for the image field.
  9514. If you specify the gxNoSpace constant for the space field, QuickDraw GX chooses an appropriate color space for you, based on the value of the pixelSize field. 
  9515. If you specify the color space yourself, you must be sure the pixel size of that color space matches the value you indicate in the pixelSize field.
  9516. For a discussion of pixel images, bitmap width, bitmap height, and pixel size, see “Bitmap Geometries” beginning on page 5-4. For a detailed discussion of color spaces, color sets, and color profiles, see the chapter “Color Objects” in Inside Macintosh: QuickDraw GX Objects.
  9517. For examples of creating gxBitmap data structures and bitmap shapes, see “Creating and Drawing Bitmaps” beginning on page 5-13.
  9518. The Long Rectangle Structure
  9519.  
  9520. The gxLongRectangle structure allows you to specify a rectangular subsection of the pixel image of a bitmap shape. It differs from the gxRectangle structure, described in the chapter “Geometric Shapes” in this book, in that the coordinates of a gxLongRectangle structure have no fractional part.
  9521. struct gxLongRectangle {
  9522.     long            left;
  9523.     long            top;
  9524.     long            right;
  9525.     long            bottom;
  9526. };
  9527. Field descriptions
  9528. left    The left side of the rectangle in number of pixels.
  9529. top    The top of the rectangle in number of pixels.
  9530. right    The right side of the rectangle number of in pixels.
  9531. bottom    The bottom of the rectangle number of in pixels.
  9532. You use the gxLongRectangle structure when editing parts of a bitmap, as discussed in “Editing Parts of a Bitmap” beginning on page 5-49.
  9533. Constants For Bitmaps With Disk-Based Pixel Images
  9534.  
  9535. QuickDraw GX provides two constants for you to use when creating bitmaps with disk-based pixel images.
  9536. #define            gxBitmapFileAliasImageValue                                        0x00000001
  9537. #define            gxBitmapFileAliasTagType                                        'bfil'
  9538. You indicate that a bitmap uses a disk-based pixel image by setting the bitmap geometry’s image field to the gxBitmapFileAliasImageValue constant. You specify which file contains the pixel image in a bitmap data source alias structure, which you attach to the bitmap using a tag with the gxBitmapFileAliasTagType tag type.
  9539. For an example of a bitmap with a disk-based pixel image, see “Creating Bitmaps With Disk-Based Pixel Images” beginning on page 5-40.
  9540. Bitmap Data Source Alias Structure 
  9541.  
  9542. QuickDraw GX provides the bitmap data source alias structure to allow you to specify file information for disk-based pixel images.
  9543. struct gxBitmapDataSourceAlias {
  9544.     unsigned long             fileOffset;                     /* file offset (in bytes) */
  9545.     unsigned long             aliasRecordSize;                             /* size of alias record */
  9546.     unsigned char             aliasRecord[gxAnyNumber];     /* alias record */
  9547. };
  9548. Field descriptions
  9549. fileOffset    The offset in bytes from the beginning of the file to the first pixel value of the pixel image.
  9550. aliasRecordSize
  9551. The size in bytes of of the alias record.
  9552. aliasRecord    A Macintosh Alias Manager alias record specifying the file containing the pixel image.
  9553. For an example of a bitmap with a disk-based pixel image, see “Creating Bitmaps With Disk-Based Pixel Images” beginning on page 5-40.
  9554. Functions
  9555.  
  9556. This section describes the functions provided by QuickDraw GX specifically for creating and manipulating bitmap shapes. With the functions described in this section, you can
  9557. n    create a new bitmap shape
  9558. n    determine and replace the geometry of a bitmap shape
  9559. n    edit a single pixel of a bitmap
  9560. n    examine or replace a rectangular subsection of a bitmap
  9561. The section “Applying Functions Described Elsewhere to Bitmap Shapes,” which begins on page 5-51, contains information about other QuickDraw GX functions that you can apply to bitmap shapes.
  9562. Creating Bitmaps
  9563.  
  9564. This section describes the function you use to create new bitmap shapes.
  9565. The GXNewBitmap function requires that you specify information about the bitmap in a bitmap geometry structure and the function encapsulates that information in a new bitmap shape.
  9566. GXNewBitmap  
  9567.  
  9568. You can use the GXNewBitmap function to create a new bitmap shape.
  9569. gxShape GXNewBitmap(const gxBitmap *data, 
  9570.                           const gxPoint *position);
  9571. data    A pointer to a bitmap geometry structure that specifies information about the bitmap shape you want to create.
  9572. position    A pointer to a point structure that indicates the initial position of the upper-right corner of the bitmap. You may set this parameter to nil to indicate (0, 0).
  9573. function result    A reference to the newly created bitmap shape.
  9574. DESCRIPTION
  9575. The GXNewBitmap function creates a new bitmap shape and returns a reference to that shape as its function result.
  9576. You specify the initial position of the new bitmap in the position parameter, and you specify the rest of the bitmap geometry by creating a gxBitmap structure and passing a pointer to it in the data parameter. 
  9577. You must provide values for the width, height, and pixelSize fields of this bitmap geomtry structure. 
  9578. Implementation Note
  9579. Version 1.0 of QuickDraw GX limits the bitmap width and the bitmap height to 32767.u
  9580. You may also specify the pixel image in the image field of the bitmap geometry structure, or you may set this field to nil, in which case QuickDraw GX allocates memory for the pixel image based on the requested width, height, and pixel size. If you supply the pixel image, you must also supply an appropriate value in the rowBytes field of the bitmap geometry structure. If QuickDraw GX allocates the pixel image, you do not have to initialize the rowBytes field.
  9581. You may indicate a color space for the bitmap in the space field of the bitmap geometry structure, but the pixel size of that color space must match the pixel size you specify in the pixelSize field. If you specify the gxNoSpace constant for the space field, QuickDraw GX chooses a color space for you:
  9582. n    If you indicate in the pixelSize field a pixel size of 16 or 32, QuickDraw GX chooses the gxRgb16Space color space or the gxRgb32Space color space, respectively.
  9583. n    If you indicate in the pixelSize field a pixel size of 1, 2, 4, or 8, QuickDraw GX chooses the gxIndexedSpace color space, and creates a grayscale color set of the appropriate size.
  9584. If you indicate the gxIndexedSpace color space for the space field, you must provide a color set in the set field.
  9585. In the profile field, you may provide a reference to a color profile describing the color matching information for the device on which the bitmap was created, or you may set this field to nil.
  9586. SPECIAL CONSIDERATIONS
  9587. If no error results, the GXNewBitmap function creates a bitmap shape; you are responsible for disposing of this shape when you no longer need it. See Inside Macintosh: QuickDraw GX Objects for information about creating and disposing of shapes.
  9588. RESULT CODESErrors    
  9589. out_of_memory    
  9590. parameter_is_nil    
  9591. parameter_out_of_range    
  9592. inconsistent_parameters    
  9593. size_of_bitmap_exceeds_implementation_limit    
  9594.  
  9595. SEE ALSO
  9596. For examples of this function, see “Creating and Drawing Bitmaps” beginning on page 5-13.
  9597. For information about the gxBitmap structure, see “The Bitmap Geometry Structure” beginning on page 5-58.
  9598. For information about bitmap width, height, and pixel size, see “Bitmap Geometries” beginning on page 5-4.
  9599. For information about disposing of bitmap shapes, see the description of the GXDisposeShape function, which is in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  9600. For a complete discussion of the QuickDraw GX color architecture, see the chapter“Color Objects” in Inside Macintosh: QuickDraw GX Objects.
  9601. Getting and Setting Bitmap Geometries
  9602.  
  9603. This section describes the functions you can use to examine or replace the geometry of a bitmap shape.
  9604. The GXGetBitmap function copies the information from the geometry of a bitmap shape into a bitmap data structure.
  9605. The GXSetBitmap function replaces the geometry of a bitmap shape with information you provide in a bitmap data structure.
  9606. GXGetBitmap  
  9607.  
  9608. You can use the GXGetBitmap function to obtain a copy of the information in a bitmap shape’s geometry.
  9609. gxBitmap *GXGetBitmap(gxShape source, const gxBitmap *data,
  9610.                                 const gxPoint *position);
  9611. source    A reference to the bitmap shape whose geometry you want to copy.
  9612. data    A pointer to a bitmap geometry structure. On return, this structure contains information copied from the geometry of the bitmap shape.
  9613. position    A pointer to a point structure. On return, this structure indicates the position of the upper-left corner of the bitmap shape.
  9614. function result    A pointer to a bitmap geometry structure containing information from the the geometry of the bitmap shape. This value is the same as the value returned in the data parameter.
  9615. DESCRIPTION
  9616. The GXGetBitmap function copies the information from the geometry of the bitmap shape indicated by the source parameter to the bitmap geometry structure pointed to by the data parameter and returns a pointer to this information as its function result. This function also copies the bitmap position from the bitmap geometry to the point structure pointed to by the position parameter.
  9617. You must create a bitmap geometry structure and a point structure to contain the copied information and pass pointers to them in the data and position parameter, respectively.
  9618. RESULT CODESErrors    
  9619. out_of_memory    
  9620. shape_is_nil    
  9621. parameter_is_nil    
  9622. illegal_type_for_shape    
  9623.  
  9624. SEE ALSO
  9625. For information about the gxBitmap structure, see “The Bitmap Geometry Structure” beginning on page 5-58.
  9626. For information about pixel images, see “Bitmap Geometries” beginning on page 5-4.
  9627. To create a bitmap shape, use the GXNewBitmap function, which is described on page 5-62.
  9628. To change the geometry of a bitmap shape, use the GXSetBitmap function, which is described in the next section.
  9629. GXSetBitmap  
  9630.  
  9631. You can use the GXSetBitmap function to change the information in the geometry of a bitmap shape.
  9632. void GXSetBitmap(gxShape target, const gxBitmap *data,
  9633.                       const gxPoint *position);
  9634. target    A reference to the bitmap shape whose geometry you want to change.
  9635. data    A pointer to a bitmap geometry structure containing new information for the geometry of the target bitmap shape.
  9636. position    A pointer to a point structure indicating the new bitmap position for the target bitmap shape.
  9637. DESCRIPTION
  9638. The GXSetBitmap function uses information you provide both in the bitmap geometry structure pointed to by the data parameter and the point structure pointed to by the position parameter to change the information in the geometry of the bitmap shape referenced by the target parameter. If the target shape is not a bitmap shape, this function converts the target shape to a bitmap shape before setting the geometry of the shape.
  9639. You can change only the bitmap position by creating a poin structure, setting its fields to reflect the new position, passing a pointer to it in the position parameter, and setting the data parameter to nil.
  9640. You can change other information in the geometry of the target bitmap shape by providing new information in a bitmap geometry structure and passing a pointer to this structure in the data parameter.
  9641. If the pixel image of the target bitmap shape was not allocated by QuickDraw GX (for example, if you allocated the pixel image yourself before calling the GXNewBitmap function), then the GXSetBitmap function simply replaces the information in the geometry of the target bitmap shape with information from the fields of the bitmap geometry structure pointed to by the data parameter.
  9642. However, if QuickDraw GX allocated the pixel image of the target bitmap shape, you can use this function to change the dimensions of the existing pixel image.
  9643. You can change the bitmap height by providing a new height in the height field of the bitmap geometry structure. You can change the bitmap width in one of two ways:
  9644. n    You can provide a new number of bytes per row in the rowBytes field of the bitmap data structure.
  9645. n    Alternatively, you can set the rowBytes field to 0 and provide a new bitmap width in the width field of the bitmap geometry structure. In this case, QuickDraw GX calculates an appropriate number of bytes per row.
  9646. In either case, this function does not scale the original pixel image; instead, it changes the amount of memory allocated to hold the pixel image. If you decrease the dimensions of the pixel image, QuickDraw GX fits the pixels in the original pixel image into a smaller space in memory, thereby losing some of the original pixel values. If you increase the dimensions of the pixel image, QuickDraw GX allocates more memory (possibly moving the original pixel image), thereby adding uninitialized pixels to the pixel image.
  9647. If QuickDraw GX allocated the original pixel image, you can also change the pixel size of the bitmap shape. You provide the new pixel size in the pixelSize field of the bitmap geometry structure and the GXSetBitmap function expands or compresses the image to fit in the new pixel size. If you specify a smaller pixel size than the original, this function redistributes the colors in the color space of the bitmap shape.
  9648. RESULT CODESErrors    
  9649. out_of_memory    
  9650. shape_is_nil    
  9651. parameter_is_nil    
  9652. parameter_out_of_range    
  9653. inconsistent_parameters    
  9654. illegal_type_for_shape    
  9655. size_of_bitmap_exceeds_implementation_limit    
  9656. Warnings    
  9657. shape_access_not_allowed    
  9658.  
  9659. SEE ALSO
  9660. For information about the gxBitmap structure, see “The Bitmap Geometry Structure” beginning on page 5-58.
  9661. For information about pixel images, bitmap height, bitmap width, pixel size, and number of rows per byte, see “Bitmap Geometries” beginning on page 5-4.
  9662. For a complete discussion of the QuickDraw GX color architecture, see the chapter “Color Objects” in Inside Macintosh: QuickDraw GX Objects.
  9663. To create a bitmap shape, use the GXNewBitmap function, which is described on page 5-62.
  9664. To obtain a copy of the information from the geometry of a bitmap shape, use the GXGetBitmap function, which is described on page 5-64.
  9665. Editing Bitmaps
  9666.  
  9667. This section describes the functions you can use to examine and change information in the pixel image of a bitmap shape.
  9668. The GXGetShapePixel function allows you to examine the value of a single pixel. The GXSetShapePixel function allows you to change the value of a single pixel.
  9669. The GXGetBitmapParts function allows you to extract a rectangular section of one bitmap shape and encapsulate it in another bitmap shape. The GXSetBitmapParts function allows you to replace a rectangular section of one bitmap shape with the pixel image of another bitmap shape.
  9670. GXGetShapePixel  
  9671.  
  9672. You can use the GXGetShapePixel function to determine the pixel value and the pixel offset of a specific pixel in a bitmap shape.
  9673. long GXGetShapePixel(gxShape source, long x, long y, 
  9674.                             gxColor *data, long *index);
  9675. source    A reference to the bitmap shape containing the pixel to examine.
  9676. x    The index of the column in which the pixel lies.
  9677. y    The index of the row in which the pixel lies.
  9678. data    A pointer to a gxColor structure. On return, this structure contains the color value of the specified pixel.
  9679. index    On return, this value contains the color value of the specified pixel (if the pixel size of the bitmap is 16 or 32) or the specified pixel’s index into the bitmap’s color set (if the pixel size of the bitmap is 1, 2, 4, or 8).
  9680. function result    The index of the byte containing the specified pixel in the source bitmap’s pixel image .
  9681. DESCRIPTION
  9682. The GXGetShapePixel function copies the pixel value of the pixel determined by the x and y parameters from the source bitmap shape into the gxColor structure pointed to by the data parameter. 
  9683. If the source bitmap shape has the keepShapeDirect shape attribute set, this function also determines the pixel offset of the specified pixel and returns it in the long value pointed to by the index parameter. This function also returns a pointer to this value as the function result.
  9684. RESULT CODESErrors    
  9685. out_of_memory    
  9686. shape_is_nil    
  9687. parameter_is_nil    
  9688. Warnings    
  9689. point_does_not_intersect_bitmap    
  9690.  
  9691. SEE ALSO
  9692. For information about the gxBitmap structure, see “The Bitmap Geometry Structure” beginning on page 5-58.
  9693. For information about pixels, pixel values, and pixel offsets, see “Bitmap Geometries” beginning on page 5-4.
  9694. To examine a more than a single pixel of a bitmap, use the GXGetBitmapParts function, which is described on page 5-70.
  9695. To change the value of a pixel, use the GXSetShapePixel function, which is described in the next section.
  9696. GXSetShapePixel  
  9697.  
  9698. You can use the GXSetShapePixel function to change the pixel value of a specific pixel in a bitmap shape.
  9699. void GXSetShapePixel(gxShape target, long x, long y, 
  9700.                            const gxColor *newColor, long newIndex);
  9701. target    A reference to the bitmap shape containing the pixel to change.
  9702. x    The index of the column in which the pixel lies.
  9703. y    The index of the row in which the pixel lies.
  9704. newColor    A pointer to a gxColor structure indicating the new pixel value of the specified pixel. You may specify nil for this parameter if the target bitmap shape has the gxIndexedSpace color space.
  9705. newIndex    An index into a color set. You may use this parameter to set the pixel value if the target bitmap shape has the gxIndexedSpace color space.
  9706. DESCRIPTION
  9707. The GXSetShapePixel function sets the pixel value of a specific pixel in the target bitmap. The pixel is determined by the values you provide in the x and y parameters. The new pixel value is determined by the newColor or newIndex parameter:
  9708. n    If you provide a color value in the newColor parameter, this function sets the pixel value of the specified pixel to be the closest color available in the color space of the target bitmap shape—even if the target bitmap shape has the gxIndexedSpace color space.
  9709. n    Alternatively, and only if the target bitmap shape has the gxIndexedSpace color space, you may provide nil for the newColor parameter and provide in the newIndex parameter a new index into the color set of the bitmap shape.
  9710. RESULT CODESErrors    
  9711. out_of_memory    
  9712. shape_is_nil    
  9713. parameter_is_nil    
  9714. Warnings    
  9715. point_does_not_intersect_bitmap    
  9716.  
  9717. SEE ALSO
  9718. For information about the gxBitmap structure, see “The Bitmap Geometry Structure” beginning on page 5-58.
  9719. For information about pixels, pixel values, and pixel offsets, see “Bitmap Geometries” beginning on page 5-4.
  9720. To change more than a single pixel of a bitmap, use the GXSetBitmapParts function, which is described on page 5-71.
  9721. To examine the value of a pixel, use the GXGetShapePixel function, which is described on page 5-64.
  9722. GXGetBitmapParts  
  9723.  
  9724. You can use the GXGetBitmapParts function to extract a rectangular section of pixels from a bitmap.
  9725. gxShape GXGetBitmapParts(gxShape source, 
  9726.                                  const gxLongRectangle *bounds);
  9727. source    A reference to the bitmap shape containing the pixels to extract.
  9728. bounds    A pointer to a rectangle indicating which part of the bitmap to extract.
  9729. function result    A reference to a new bitmap shape containing only the extracted section of the source bitmap shape.
  9730. DESCRIPTION
  9731. The GXGetBitmapParts function extracts the pixels whose row index and column index fall within the boundaries of the rectangle pointed to by the bounds parameter, encapsulates the extracted pixel image in a new bitmap shape, and returns a reference to the new bitmap shape as the function result.
  9732. The returned bitmap shape has the same pixel size as the source bitmap shape, the returned bitmap shape also shares the same color space, color set, and color profile as the source bitmap shape.
  9733. The pixel image of the returned bitmap is allocated in QuickDraw GX memory.
  9734. RESULT CODESErrors    
  9735. out_of_memory    
  9736. shape_is_nil    
  9737. parameter_is_nil    
  9738. point_does_not_intersect_bitmap    
  9739. parameter_out_of_range    
  9740. shape_does_not_contain_a_bitmap    
  9741.  
  9742. SEE ALSO
  9743. For examples of this function, see “Editing Parts of a Bitmap” beginning on page 5-49.
  9744. For information about the gxBitmap structure, see “The Bitmap Geometry Structure” beginning on page 5-58.
  9745. For information about the gxLongRectangle structure, see “The Long Rectangle Structure” beginning on page 5-60.
  9746. For information about pixels and pixel images, see “Bitmap Geometries” beginning on page 5-4.
  9747. To examine a single pixel of a bitmap, use the GXGetShapePixel function, which is described on page 5-68.
  9748. To change a section of a bitmap, use the GXSetBitmapParts function, which is described in the next section.
  9749. GXSetBitmapParts  
  9750.  
  9751. You can use the GXSetBitmapParts function to replace the pixel values in a rectangular subsection of a bitmap’s pixel image.
  9752. void GXSetBitmapParts(gxShape target, const gxRectangle *bounds,
  9753.                             gxShape bitmapShape);
  9754. target    A reference to the bitmap shape containing the pixels to replace.
  9755. bounds    A pointer to a rectangle indicating which part of the target bitmap to replace.
  9756. bitmapShape
  9757. A reference to a bitmap shape containing the pixel values to use when replacing the specified pixels in the target bitmap shape.
  9758. DESCRIPTION
  9759. The GXSetBitmapParts function copies the pixel values (starting at the upper-left corner of the pixel image) of the source bitmap shape (which is indicated by the bitmapShape parameter) to the pixel image of the target bitmap shape. The bounds parameter determines how many rows and columns this function copies and where in the target bitmap the function places the copied pixel values.
  9760. The pixel image of the source bitmap may not be smaller than the size indicated by the bounds parameter; that is, the number of rows and columns in the pixel image of the source bitmap shape may not be less than the height and width of the specified rectangle, respectively.
  9761. The source and target bitmap shapes must have the same pixel size, color space, and color set.
  9762. RESULT CODESErrors    
  9763. out_of_memory    
  9764. shape_is_nil    
  9765. parameter_is_nil    
  9766. point_does_not_intersect_bitmap    
  9767. parameter_out_of_range    
  9768. shape_access_not_allowed    
  9769. shape_does_not_contain_a_bitmap    
  9770.  
  9771. SEE ALSO
  9772. For examples of this function, see “Editing Parts of a Bitmap” beginning on page 5-49.
  9773. For information about the gxBitmap structure, see “The Bitmap Geometry Structure” beginning on page 5-58.
  9774. For information about the gxLongRectangle structure, see “The Long Rectangle Structure” beginning on page 5-60.
  9775. For information about pixels and pixel images, see “Bitmap Geometries” beginning on page 5-4
  9776. To change the pixel value of a single pixel, use the GXSetShapePixel function, which is described on page 5-69.
  9777. To extract a rectangular subsection of a bitmap, use the GXGetBitmapParts function, which is described on page 5-70.
  9778. Drawing Bitmaps
  9779.  
  9780. QuickDraw GX provides two methods of drawing a bitmap:
  9781. n    You can create a bitmap shape (by calling the GXNewBitmap function, by copying an existing bitmap shape, and so on) and use the GXDrawShape function to draw the bitmap.
  9782. n    You can create a bitmap geometry structure and use the GXDrawBitmap function to draw the bitmap.
  9783. In general, you should use the GXDrawShape function to draw any QuickDraw GX graphic, including bitmap shapes. In fact, the GXDrawBitmap function creates a temporary bitmap shape, uses the GXDrawShape function to draw it, and then disposes of it. The GXDrawShape function is described in the chapter “Shape Objects” in Inside Macintosh: QuickDraw GX Objects.
  9784. You would typically use the GXDrawBitmap function only in simple situations—for example, if you knew you wanted to draw a particular bitmap only once. 
  9785. GXDrawBitmap  
  9786.  
  9787. You can use the GXDrawBitmap function to draw a bitmap without encapsulating the bitmap geometry in a bitmap shape.
  9788. void GXDrawBitmap(const gxBitmap *data, const gxPoint *position);
  9789. data    A pointer to a bitmap geometry structure that specifies information about the bitmap you want to draw.
  9790. position    A pointer to a point structure which indicates the position to draw the bitmap.
  9791. DESCRIPTION
  9792. The GXDrawBitmap function allows you to draw a bitmap without having to create a bitmap shape yourself. Instead, you create a bitmap geometry structure specifying the bitmap you want to draw and a point structure indicating the position of the bitmap, and then you pass a pointer to these structures in the data and position parameters, respectively.
  9793. The GXDrawBitmap function calls the GXNewBitmap function to create a temporary bitmap shape using the values specified in these structures and the style, ink and transform of the default bitmap shape. Then the GXDrawBitmap function draws the bitmap shape using the GXDrawShape function.
  9794. For information about how QuickDraw GX creates bitmap shapes using the values you provide in the fields of the bitmap data structure, see the description of the GXNewBitmap function on page 5-62.
  9795. RESULT CODESErrors    
  9796. out_of_memory    
  9797. shape_is_nil    
  9798. parameter_is_nil    
  9799. parameter_out_of_range    
  9800. inconsistent_parameters    
  9801. illegal_type_for_shape    
  9802. size_of_bitmap_exceeds_implementation_limit    
  9803.  
  9804. SEE ALSO
  9805. For examples of this function, see “Creating Black-and-White Bitmaps” beginning on page 5-14.
  9806. For information about the gxBitmap data structure, see “The Bitmap Geometry Structure” beginning on page 5-58.
  9807. To encapsulate a bitmap geometry in a bitmap shape, use the GXNewBitmap function, which is described on page 5-62.
  9808. To draw a bitmap once you’ve encapsulated it in a bitmap shape, use the GXDrawShape function, which is described in the “Shape Objects” chapter of Inside Macintosh: QuickDraw GX Objects.
  9809. Checking Bitmap Colors
  9810.  
  9811. QuickDraw GX provides the GXCheckBitmapColor function to allow you to determine which pixels in a bitmap are in a specified color space or color set, and which are not.
  9812. GXCheckBitmapColor
  9813.  
  9814. You can use the GXCheckBitmapColor function to determine whether the color values in a bitmap’s pixel image are in a given color space or color set.
  9815. gxShape GXCheckBitmapColor(gxShape source, 
  9816.                                     const gxLongRectangle *area,
  9817.                                     gxColorSpace space, gxColorSet aSet,
  9818.                                      gxColorProfile profile);
  9819. source    A reference to the bitmap shape whose pixels you want to check.
  9820. area    A long rectangle specifying the area of the bitmap to check. You can specify a value of nil for this parameter to check the entire bitmap.
  9821. space    The color space to check the pixel values of the source bitmap against. You can provide the gxIndexedSpace constant for this parameter to indicate that you want to test the pixel values against a color set.
  9822. aSet    A reference to the color set to check the pixel values of the source bitmap against. 
  9823. profile    A pointer to the color profile to use when checking the pixel values of the source bitmap.
  9824. function result    A new bitmap shape with a pixel size of one bit-per-pixel. Each pixel in this bitmap is set to a value of 0 if the corresponding pixel in the source bitmap is in the specified color space or color set and is set to a value of 1 if the corresponding pixel in the source bitmap is not in the specified color space.
  9825. DESCRIPTION
  9826. This GXCheckBitmapColor function determines whether the color values of the pixels in the source bitmap are in the color space or color set indicated by the space and aSet parameters. You can check a rectangular subsection of the source bitmap’s pixel image using the area parameter to specify the subsection to check.
  9827. This function calls the GXCheckColor function for each specified pixels and returns the results of that function in a the pixel image of a new bitmap shape.
  9828. RESULT CODES
  9829. (*** Need these. ***)
  9830. SEE ALSO
  9831. For information about colors, color spaces, color sets, color profiles, and the GXCheckColor function, see chapter “Colors and Color-Related Objects” in Inside Macintosh: QuickDraw GX Objects.
  9832.  
  9833.  
  9834. Summary of Bitmap Shapes
  9835.  
  9836. Data Types
  9837.  
  9838. Bitmap Geometries
  9839. typedef struct {
  9840.     char                     *image;                    /* pointer to the pixel image */
  9841.     long                     width;                    /* bitmap width */
  9842.     long                     height;                    /* bitmap height */
  9843.     long                     rowBytes;                    /* number of bytes per row */
  9844.     long                     pixelSize;                    /* number of bits per pixel */
  9845.     gxColorSpace                     space;                    /* color space */
  9846.     gxColorSet                     set;                    /* color set */
  9847.     gxColorProfile                 profile;                        /* color profile */
  9848. } gxBitmap;
  9849. Long Rectangles
  9850. struct gxLngRectangle {
  9851.     long            left;
  9852.     long            top;
  9853.     long            right;
  9854.     long            bottom;
  9855. };
  9856. Constants For Bitmaps With Disk-Based Pixel Images
  9857. #define            gxBitmapFileAliasImageValue                                        0x00000001
  9858. #define            gxBitmapFileAliasTagType                                        'bfil'
  9859. Bitmap Data Source Alias Structure 
  9860. struct gxBitmapDataSourceAlias {
  9861.     unsigned long             fileOffset;                     /* file offset (in bytes) */
  9862.     unsigned long             aliasRecordSize;                             /* size of alias record */
  9863.     unsigned char             aliasRecord[gxAnyNumber];     /* alias record */
  9864. };
  9865. Functions
  9866.  
  9867. Creating Bitmaps
  9868. gxShape GXNewBitmap    (const gxBitmap *data, const gxPoint *position);
  9869. Getting and Setting Bitmap Geometries
  9870. gxBitmap *GXGetBitmap    (gxShape source, const gxBitmap *data,
  9871. const gxPoint *position);
  9872. void GXSetBitmap    (gxShape target, const gxBitmap *data,
  9873. const gxPoint *position);
  9874. Editing Bitmaps
  9875. long GXGetShapePixel    (gxShape source, long x, long y, gxColor *data,
  9876. long *index);
  9877. void GXSetShapePixel    (gxShape target, long x, long y, 
  9878. const gxColor *newColor, long newIndex);
  9879. gxShape GXGetBitmapParts    (gxShape source, const gxLongRectangle *bounds);    
  9880. void GXSetBitmapParts    (gxShape target, const gxLongRectangle *bounds,
  9881. gxShape bitmapShape);
  9882. Drawing Bitmaps
  9883. void GXDrawBitmap    (const gxBitmap *data, const gxPoint *position);
  9884. Checking Bitmap Colors
  9885. gxShape GXCheckBitmapColor    (gxShape source, 
  9886. const gxLongRectangle *area,
  9887. gxColorSpace space, gxColorSet aSet,
  9888. gxColorProfile profile);
  9889. Listing 6-0
  9890. Table 6-0
  9891. Picture Shapes
  9892. Contents
  9893. About Picture Shapes6-3
  9894. Overriding Styles, Inks, and Transforms6-7
  9895. Multiple References6-9
  9896. Unique Items Attribute6-13
  9897. Picture Hierarchies6-14
  9898. Transform Concatenation6-15
  9899. Hit-Testing Picture Shapes6-20
  9900. Using Picture Shapes6-22
  9901. Creating and Drawing Picture Shapes6-22
  9902. Getting and Setting Picture Geometries6-26
  9903. Adding Items to a Picture6-28
  9904. Removing and Replacing Items in a Picture6-31
  9905. Overriding Styles, Inks, and Transforms6-33
  9906. Adding Multiple References6-35
  9907. Adding Unique Items6-37
  9908. Creating Picture Hierarchies6-39
  9909. Hit-Testing Pictures6-40
  9910. Applying Functions Described Elsewhere to Picture Shapes6-46
  9911. Functions That Post Errors or Warnings6-46
  9912. Shape-Related Functions6-47
  9913. Geometric Operations6-48
  9914. Style-Related Functions6-49
  9915. Ink- and Color-Related Functions6-49
  9916. Transform- and View-Related Functions6-49
  9917. Picture Shapes Reference6-50
  9918. Functions6-50
  9919. Creating Picture Shapes6-50
  9920. GXNewPicture 6-50
  9921. Getting and Setting Picture Geometries6-52
  9922. GXGetPicture 6-52
  9923. GXSetPicture 6-53
  9924. Editing Picture Parts6-55
  9925. GXGetPictureParts 6-55
  9926. GXSetPictureParts 6-57
  9927. Drawing Pictures6-59
  9928. GXDrawPicture 6-60
  9929. Hit-Testing Pictures6-61
  9930. GXHitTestPicture 6-61
  9931. Summary of Picture Shapes6-64
  9932. Data Types6-64
  9933. Functions6-64
  9934. Picture Shapes
  9935. QuickDraw GX provides four basic types of shapes:
  9936. n    geometric shapes
  9937. n    typographic shapes
  9938. n    bitmap shapes
  9939. n    picture shapes
  9940. This chapter describes picture shapes and the functions you use to manipulate them. It also discusses the functions described in other chapters that you can apply to picture shapes.
  9941. In particular, this chapter shows you how you can create and draw picture shapes; edit a picture shape’s list of items; override style, ink, and transform information for items in a picture; create picture hierarchies; and hit-test picture shapes.
  9942. You should be familiar with the information in the chapter “Shape Objects” of Inside Macintosh: QuickDraw GX Objects before you read this chapter, and you will probably want to be familiar with the information in the chapter “Transform Objects” of that book. You might also want to be familiar with the other shape types, which are described in Chapter 2, “Geometric Shapes,” and Chapter 5, “Bitmap Shapes,” of this book, as well as in the chapter “Typographic Shapes” of Inside Macintosh: QuickDraw GX Typography.
  9943.  
  9944. About Picture Shapes
  9945.  
  9946. A picture shape represents a collection of other shapes. For example, you could create a scroll bar using a picture shape:
  9947. n    You could create separate polygon shapes to represent the scroll box, the gray area, and the two scroll arrows. 
  9948. n    You could then collect these individual polygon shapes into a single picture shape to represent the entire scroll bar.
  9949. Using picture shapes, you can create complex graphics, create shapes with both graphic and typographic content, combine multiple bitmaps into a single shape, create groups of shapes, create shape layers, group shapes into pages to prepare for printing, and so on.
  9950. Like any QuickDraw GX shape, a picture shape is represented in memory by a shape object, a style object, an ink object, and a transform object. A shape object representing a picture shape contains the same properties as a shape object representing a geometric or a typographic shape: owner count, tag list, shape type, shape fill, geometry, and so on.
  9951. Since picture shapes contain other shapes, they doen’t make much use of their shape fill property, although you can specify a no-fill shape fill if you don’t want the picture to appear when drawn. 
  9952. Picture shapes also don’t make much use of their associated style object, since each shape in the picture has its own style object, and, potentially, an overriding style object.
  9953. Pictures shapes also don’t make much use of their ink objects for the same reasons.
  9954. Picture shapes do make full use of their transform objects, however. For example, you can scale, skew, rotate, and clip picture shapes as a whole, as well as separately for each individual shape in the picture. This process is described in more detail in the section “Transform Concatenation” beginning on page 6-15.
  9955. Figure 6-1 shows a graphic representation of a picture shape and a picture geometry.
  9956. Figure 6-1    A picture shape
  9957.  
  9958. Picture shapes differ from other types of shapes primarily in the content of their geometries. A picture shape’s geometry contains a list of picture items. Each picture item contains a reference to another shape.
  9959. Although each of the shapes in a picture has its own style, ink, and transform object, picture shapes allow you to provide an overriding style, ink, and transform object for each of these shapes. QuickDraw GX uses this overriding information only when drawing the picture. Even after you insert a shape into a picture, you can still draw the original shape using its original style, ink, and transform object.
  9960. Figure 6-1 shows a single picture item. This item contains a reference to a shape object, which contains a reference to its associated style, ink, and transform objects. These objects are shown in grey, because the picture item also contains references to an overriding style, ink, and transform object for the shape. For an example of the effects of the overriding style, ink, and transform objects, see the next section, “Overriding Styles, Inks, and Transforms” beginning on page 6-7.
  9961. Figure 6-2    A picture item
  9962.  
  9963. Figure 6-1 shows an example of a picture shape with a geometry that contains two picture items. Each item contains a reference to a shape, but neither item contains a reference to an overriding style, ink, or transform object. Therefore, when QuickDraw GX draws this picture, it draws each shape in the picture using the style, ink, and transform information originally associated with the shape, as shown at the bottom of Figure 6-1.
  9964. Figure 6-3    A picture geometry with two items
  9965.  
  9966. Notice that QuickDraw GX draws the shapes in a picture in the order the references to them appear in the picture geometry, from back to front.
  9967. Figure 6-1 shows the entire shape object and picture geometry for the picture shape. Figure 6-1 shows a condensed view of the same picture. This chapter uses condensed views of picture shapes when drawing picture hierarchies, which are described in “Picture Hierarchies” beginning on page 6-14.
  9968. Figure 6-4    Condensed picture with two items
  9969.  
  9970. Overriding Styles, Inks, and Transforms
  9971.  
  9972. QuickDraw GX allows you to specify an overriding style, ink, or transform object for any item in a picture. If an item has an overriding style, ink, or transform object, QuickDraw GX uses the information in the overriding object rather than the information in the original style, ink, or transform when drawing that item of the picture shape.
  9973. Figure 6-1 shows the picture from Figure 6-1 with overriding information added. In this figure, the first picture item has an overriding ink, which specifies a dark gray color. The second picture item has an overriding style, which specifies a pattern.
  9974. Figure 6-5    A picture shape with overrides
  9975.  
  9976. When QuickDraw GX draws the picture represented in Figure 6-1, it draws the first picture item using the information in the overriding ink objects, rather than the information in the ink object originally associated with the first item. Similarly, when it draws the second shape, it uses the information in the overriding style rather than the information in the original style.
  9977. Multiple References
  9978.  
  9979. QuickDraw GX allows multiple items in a picture to reference the same shape. Figure 6-6 shows an example of a picture shape containing four items. In this example, each item references the same shape: a black rectangle.
  9980. Figure 6-6    A picture containing multiple references to the same shape
  9981.  
  9982. Figure 6-1 shows the condensed view of the picture from Figure 6-6.
  9983. Figure 6-7    A picture item
  9984.  
  9985. Although the picture shape shown in Figure 6-6 contains four references to the black rectangle, only one black rectangle appears when the picture is drawn. You might expect the rectangle to be drawn four times; however, it only appears once because each instance of the rectangle appears in the same location.
  9986. Having multiple references to the same shape becomes more useful when you add overriding information. For example, if you add overriding transforms to three of the items in the picture shape from Figure 6-6, all four items appear when the picture is drawn, as shown in Figure 6-8.
  9987. Figure 6-8    Multiple references with overriding transforms
  9988.  
  9989. The picture shape in Figure 6-8 contains four items each referencing the same black rectangle shape. However, the second, third, and fourth items contain overriding transforms. When drawing this picture shape, QuickDraw GX applies the original transform when drawing the first item, and applies the overriding transforms when drawing the second, third, and fourth items. In this way, the four items appear separate when the picture is drawn, even though all four items reference the same shape.
  9990. You can use overriding styles and inks to make multiple references even more powerful. In Figure 6-9, the second item has an overriding style as well as an overriding transform, the third item has an overriding ink as well as an overriding transform, and the fourth item has an overriding transform that moves, scales, and clips.
  9991. Figure 6-9    Multitple references with overriding styles, inks, and transforms
  9992.  
  9993. Although each item in the picture shape shown in Figure 6-9 references the same black rectangle, the use of overriding styles, inks, and transforms creates substantial variations in the items of the picture as drawn.
  9994. For more examples of multiple references and overriding styles, inks, and transforms, see “Adding Multiple References” beginning on page 6-35.
  9995. Unique Items Attribute
  9996.  
  9997. One of the shape attributes provided by QuickDraw GX is the unique items attribute. This attribute affects the way shapes are added to a picture:
  9998. n    If a picture shape does not have the unique items attribute set, QuickDraw GX adds shapes to the picture by reference.
  9999. n    If a picture shape does have the unique items attribute set, QuickDraw GX adds shapes to the picture by copying the shapes and adding a reference to the copy.
  10000. Although you may clear the unique items attribute for a picture at any time, you may set the unique items attribute only when a picture is empty—that is, only when the picture contains no items.
  10001. You set or clear the unique items attribute using the GXGetShapeAttributes function, which is described in the chapter “Shape Objects” of Inside Macintosh: QuickDraw GX Objects.
  10002. As an example, Figure 6-10 shows how QuickDraw GX adds shapes to a picture that does not have the unique items attribute set. The first part of this figure depicts an empty picture shape and a polygon shape.
  10003. The second part of this figure shows what happens when you add the polygon shape to the picture shape. QuickDraw GX adds to the picture shape a reference to the polygon shape, and increases the owner count of the polygon shape by 1.
  10004. In the third part of this figure, QuickDraw GX adds the same shape to the picture a second time. This time, QuickDraw GX adds to the picture shape a second reference to the same polygon shape, and again increases the owner count of the polygon shape by 1.
  10005. Figure 6-10    Adding shapes to a picture without the unique items attribute
  10006.  
  10007. Figure 6-11 shows the same process for a picture with the unique items attribute set.
  10008. Figure 6-11    Adding shapes to a picture with the unique items attribute
  10009.  
  10010. The first time you add a shape to a picture with the unique items attribute set, QuickDraw GX creates a copy of the shape. If you add the same shape to the picture a second time, QuickDraw GX does not create a second copy of the shape. Instead, QuickDraw GX adds a second reference to the first copy, as shown in Figure 6-11. 
  10011. In this way, QuickDraw GX avoids creating unnecessary copies when adding shapes to pictures with the unique items attribute set.
  10012. For more examples involving the unique items attribute, see “Adding Unique Items” beginning on page 6-37.
  10013. Picture Hierarchies
  10014.  
  10015. Each item of a picture shape contains a reference to another shape. These shapes can be of any type, including other picture shapes. When a picture shape contains references to other picture shapes, you have a picture hierarchy. Figure 6-12 shows a picture hiearchy. 
  10016. Figure 6-12 depicts a picture shape with two items. Each item references another picture shape, each of which also has two items.
  10017. This figure shows the condensed view of the picture hierarchy.
  10018. Figure 6-12    A condensed view of a picture hierarchy
  10019.  
  10020. Each item in a picture hierarchy has a level. The picture shape at the top of the hierarchy has a level of 0. The two items belonging to that picture shape—which are picture shapes themselves—have a level of 1. Items belonging to pictures that have a level of 1 have a level of 2, and so on. In the picture hierarchy shown in Figure 6-12, the four geometric shapes all have a level of 2.
  10021. Transform Concatenation
  10022.  
  10023. Each item in a picture shape has its own transform object and possibly an overriding transform as well. When QuickDraw GX draws a picture shape, it maps and clips each item according the mapping and clipping information stored in that item’s transform object (or the information in the item’s overriding transform, if it has one). After applying mappings and clippings to the individual items of a picture, QuickDraw GX applies a mapping and clipping to the entire picture, as indicated by the transform object associated with the picture shape. In this way, each item in the picture goes through two transformations: an individual transformation as indicated by the item’s individual transform (or overriding transform), and a group transformation as indicated by the picture shape’s transform. This process is called transform concatenation.
  10024. If a picture shape contains a picture hierarchy, QuickDraw GX repeats this concatenation process from the individual shapes at the lowest level of the hierarchy all the way up to the picture shape at the highest level of the hierarchy.
  10025. As an example, Figure 6-13 shows a path shape representing a house. This path shape has a transform that rotates it 180 degrees.
  10026. Figure 6-13    A path shape and its transform
  10027.  
  10028. Figure 6-14 shows the same path shape, but in this figure the path shape has been added to a picture shape as the picture’s only item. This item includes an overriding transform. When drawing this picture, QuickDraw GX ignores the original transform, and rotates every item in the path shape clockwise by 90 degrees, as specified in the overriding transform.
  10029. Figure 6-14    A picture with an overriding transform
  10030.  
  10031. Figure 6-15 shows the same picture shape as Figure 6-14. In Figure 6-15, however, the picture shape at the root of the picture hierarchy has its own transform object that specifies that the entire picture should be rotated counterclockwise by 90 degrees. QuickDraw GX concatentates the overriding transform of the path shape (labeled 1 in the picture) with the transform of the root picture (labeled 2 in the picture), and draws the house at its original orientation. The original transform of the path shape (labeled 1A) is ignored because of the overriding transform.
  10032. Figure 6-15    Simple transform concatenation
  10033.  
  10034. Figure 6-16 shows an even more complex example of transform concatenation. This figure shows the same picture from Figure 6-15, but in Figure 6-16 this picture has been added as an item to another picture.
  10035. To draw this picture, QuickDraw GX uses the overriding transform (labeled 1) of the original path shape, which rotates it 90 degrees to the right. Then QuickDraw GX uses the overriding transform (labeled 2) associated with the picture that contains the path shape, which scales the picture by a factor of 2. Finally, QuickDraw GX uses the transform object (labeled 3) of the root-level picture shape, which rotates the picture 45 to the right. The result is shown at the bottom of Figure 6-16.
  10036. Figure 6-16    Intricate transform concatenation
  10037.  
  10038. You can find more examples of transform concatentation in “Creating Picture Hierarchies” beginning on page 6-39.
  10039. Hit-Testing Picture Shapes
  10040.  
  10041. QuickDraw GX provides some powerful tools for hit-testing picture shapes. When the user clicks the mouse, your application receives the information from the Macintosh Toolbox about where the mouse click occurred. By sending this information to the GXHitTestPicture function, you can find which item in a picture was hit. This process is called hit-testing the picture shape.
  10042. When hit-testing picture shapes, QuickDraw GX
  10043. n    hit-tests each item contained in the picture, using the hit-test information in that item’s transform object (or overriding transform object, if the item has one) to determine if the item was hit or not
  10044. n    compiles a list of items that were hit
  10045. n    selects one of the items that were hit using selection criteria you provide
  10046. n    provides information about the selected item that was hit
  10047. Since more than one shape in a picture can be hit during a single hit-test, you provide QuickDraw GX with extra selection criteria when hit-testing a picture. Specifically, you specify a depth and a level:
  10048. n    Pictures frequently contain shapes that overlap when drawn. Therefore, it is possible that the test point hits multiple shapes. For example, if the picture contains two shapes, one on top of the other, the test point might hit both of them. You can control which of these shapes QuickDraw GX selects as the hit shape by specifying a shape depth. In this example, specifying a shape depth of 1 would indicate that QuickDraw GX should select the shape that was drawn on top as the hit shape. Specifying a shape depth of 2 would indicate that QuickDraw GX should select the shape that was drawn underneath as the hit shape.
  10049. n    In a picture hierarchy, each shape can be contained by a picture shape, which in turn can be contained by another picture shape, and so on. If the hit shape has a level of 3, for example, you can specify that QuickDraw GX return a reference to the hit shape by specifying a level of 3. You can specify that QuickDraw GX return a reference to the picture that contains the hit shape by specifying a level of 2. You can specify that QuickDraw GX return a reference to the picture that contains the picture that contains the hit shape by specifying a level of 1.
  10050. Figure 6-13 shows an example. The picture shape shown in this figure has two items, each of which are pictures. Each of these pictures has two items itself, making a total of four shapes that have a level of 2 in this hierarchy.
  10051. This figure shows the picture as drawn, and three sample hit-test points. 
  10052. Figure 6-17    A picture shape and its transform
  10053.  
  10054. The first sample hit-test point hits only one shape: the lawn path shape. The second sample hit-test point hits two shapes: at depth 1, it hits the house rectangle; at depth 2, it hits the lawn shape. The third hit-test point hits three shapes: at depth 1, it hits the house rectangle; at depth 2, it hits the walkway polygon; at depth 3, it hits the lawn shape.
  10055. For programmiing examples of hit-testing picture shapes, see “Hit-Testing Pictures” beginning on page 6-40.
  10056.  
  10057.  
  10058. Using Picture Shapes
  10059.  
  10060. This section shows you how to create, draw, edit, and hit-test picture shapes. In particular, this section shows you how to 
  10061. n    create and draw pictures
  10062. n    add items to a picture
  10063. n    remove and replace items in a picture
  10064. n    provide overriding styles, inks, and transforms for the items in a picture
  10065. n    add multiple copies of a shape to a picture
  10066. n    copy objects when adding them to a picture
  10067. n    create hierarchies of pictures
  10068. n    hit-test pictures
  10069. Although the geometry of a picture shape does not contain geometric points, a picture shape can contain shapes whose geometries do contain geometric points. For this reason, some of the sample functions in this section need to specify geometric points, which are made up of two fixed-point numbers. To convert integers to fixed-point numbers when specifying geometric points, QuickDraw GX provides the GXIntToFixed macro:
  10070. #define GXIntToFixed(a) ((fixed)(a) << 16)
  10071. QuickDraw GX also provides the ff macro as a convenient alias:
  10072. #define ff(a) GXIntToFixed(a)
  10073. The sample functions throughout this section use the ff macro when converting an integer constant to a fixed-point constant.
  10074. Creating and Drawing Picture Shapes
  10075.  
  10076. QuickDraw GX provides a number of methods to create and draw pictures. In general, you can
  10077. n    define the items of the picture and draw them without creating a picture shape
  10078. n    define the items of the picture, incorporate them into a picture shape, and draw the picture shape
  10079. You can use the GXDrawPicture function to draw pictures using the first method. You send four parameters to this function: an array of references to the shapes you want drawn, and arrays of references to the overriding styles, inks, and transforms for those shapes. (See “Overriding Styles, Inks, and Transforms” beginning on page 6-33 for examples of overriding styles, inks, and transforms.) The GXDrawPicture function creates a temporary picture shape using the information in the arrays you provide, draws the picture shape, and then disposes of the temporary picture shape. 
  10080. The GXDrawPicture function is convenient if you have a set of shapes (and overriding styles, inks, and transforms) that you want to draw only one time.
  10081. QuickDraw GX also provides a number of ways for you to create a more permanent picture shape—one that you can edit and draw repeatedly. To create a picture shape, you can
  10082. n    create an empty picture shape using the GXNewShape function and add items to the picture all at once using the GXSetPicture function
  10083. n    create an empty picture shape using the GXNewShape function and add items to the picture individually using the GXSetPictureParts function or the AddToPicture library function
  10084. n    create a picture with an initial set of items using the GXNewPicture function
  10085. In any of these three cases, you draw the picture shape using the GXDrawShape function.
  10086. The GXSetPictureParts function provides more sophisticated editing of a picture shape’s item list. For more information, see “Adding Items to a Picture” beginning on page 6-28, and “Removing and Replacing Items in a Picture” beginning on page 6-31.
  10087. The GXSetPicture function allows you to replace the entire geometry of a picture with a new set of items. For more information, see “Getting and Setting Picture Geometries” beginning on page 6-26.
  10088. The GXNewPicture function is similar to the GXDrawPicture function in that it requires four arrays as parameters: arrays of references to the shapes, the overriding styles, the overriding inks, and the overriding transforms that make up the items of the picture shape. However, unlike the GXDrawPicture function, the GXNewPicture function creates a picture shape and returns a reference to it to your application. You can use this reference to draw the picture using the GXDrawShape function.
  10089. Listing 6-1 shows how to draw a picture of a house comprising three shapes: a rectangle for the house itself, another rectangle for the door, and a triangle for the roof. The sample function shown in this listing creates three shapes and draws them using the GXDrawPicture function.
  10090. Listing 6-1    Creating a simple picture of a house
  10091.  
  10092. static gxShape DrawHousePicture(void)
  10093. {
  10094.     const gxRectangle houseGeometry = {ff(90), ff(80),
  10095.                                                   ff(200), ff(125)};
  10096.                                           
  10097.     const gxRectangle doorGeometry = {ff(155), ff(95),
  10098.                                              ff(170), ff(125)};
  10099.                                           
  10100.     const long roofGeometry[] = {1, /* number of contours */
  10101.                                         3, /* number of points */
  10102.                                         ff(80), ff(80),
  10103.                                         ff(145), ff(50),
  10104.                                         ff(210), ff(80)};
  10105.     gxShape houseRectangle;
  10106.     gxShape roofPolygon;
  10107.     gxShape doorRectangle;
  10108.     
  10109.     gxShape partsOfHouse[3];
  10110.  
  10111.  
  10112.     houseRectangle = GXNewRectangle(&houseGeometry);
  10113.     SetShapeCommonColor(houseRectangle, gxGray);
  10114.     roofPolygon = GXNewPolygons((gxPolygons *) roofGeometry);
  10115.  
  10116.     doorRectangle = GXNewRectangle(&doorGeometry);
  10117.  
  10118.     partsOfHouse[0] = houseRectangle;
  10119.     partsOfHouse[1] = roofPolygon;
  10120.     partsOfHouse[2] = doorRectangle;
  10121.  
  10122.     GXDrawPicture(3, partsOfHouse, nil, nil, nil);
  10123.  
  10124.     GXDisposeShape(houseRectangle);
  10125.     GXDisposeShape(roofPolygon);
  10126.     GXDisposeShape(doorRectangle);
  10127.  
  10128. };
  10129. The results of this sample function are shown in Figure 6-18.
  10130. Figure 6-18    A picture of a house with a roof and a door
  10131.  
  10132. The call to the GXDrawPicture function in this example creates a temporary picture shape, draws it, and then disposes of it. This function does not return a reference to the picture shape, and so your code never has access to this shape. To create a more permanent picture shape, one that your code can reference, you must first declare a shape reference variable:
  10133. gxShape housePicture;
  10134. Then you can replace the call to the GXDrawPicture function with a call to the GXNewPicture function:
  10135. housePicture = GXNewPicture(3, partsOfHouse, nil, nil, nil);
  10136. and a call to the GXDrawShape function:
  10137. GXDrawShape(housePicture);
  10138. The resulting picture looks the same as the picture drawn by the GXDrawPicture function, which is shown in Figure 6-18, but in this case the picture shape exists until you explicitly dispose of it. 
  10139. You can dispose of the picture shape using the GXDisposeShape function:
  10140. GXDisposeShape(housePicture);
  10141. In this example, disposing of the house picture also disposes of the three geometric shapes referenced by the house picture. In other words, disposing of the house picture releases one of the references to each of the geometric shapes. However, before you dispose of the house picture, each of these shapes has an owner count of 2. (The owner count of each shape starts at 1 when you create it, and the call to the GXNewPicture function increments the owner count of each of the shapes.) Therefore, when you dispose of the house picture, the owner count of each of the geometric shapes decrements to 1. To free the memory used by these shapes, you must still dispose of them individually—just as you created them:
  10142. GXDisposeShape(houseRectangle);
  10143. GXDisposeShape(roofPolygon);
  10144. GXDisposeShape(doorRectangle);
  10145. Notice that you can dispose of these three geometric shapes before you dispose of the house picture, as shown in Listing 6-2.
  10146. Listing 6-2    Disposing of shapes contained in a picture before disposing of the picture
  10147.  
  10148. housePicture = GXNewPicture(3, partsOfHouse, nil, nil, nil);
  10149.  
  10150. GXDisposeShape(houseRectangle);
  10151. GXDisposeShape(roofPolygon);
  10152. GXDisposeShape(doorRectangle);
  10153.  
  10154. GXDrawPicture(housePicture);
  10155.  
  10156. GXDisposeShape(housePicture);
  10157. In this example, disposing the three geometric shapes decrements their owner count by 1, but does not free their memory because the house picture shape still contains a reference to each of the three shapes. Only when the house picture is disposed of is the memory occupied by these three geometric shapes freed.
  10158. For information about the GXDrawPicture function, see page 6-60. For information about the GXNewPicture function, see page 6-50.
  10159. Getting and Setting Picture Geometries
  10160.  
  10161. QuickDraw GX provides the GXGetPicture function and the GXSetPicture function to allow you to examine and replace the entire geometry of a picture shape.
  10162. The GXGetPicture function returns as its function result the number of items in the picture, and optionally returns an array of references to the shapes referenced by the picture’s items, as well as arrays of references to the picture items’ overriding styles, inks, and transforms. Typically, you call this function twice. The first time you determine the number of items in the picture. Then you use that number to allocate enough memory to hold the arrays of references. Finally, you call the function a second time to copy references from the items of the picture into your arrays.
  10163. The GXSetPicture function allows you to replace the geometry of a picture with a new set of items. This function disposes of the shapes, overriding styles, overriding inks, and overriding transforms that previously existed in the picture, and increments the owner counts of the new shapes, overriding styles, overriding inks, and overriding transforms.
  10164. Listing 6-3 gives an example of the GXGetPicture function. This example, which builds on the example from Listing 6-1 on page 6-23, edits the picture of the house by moving the location of the door.
  10165. Listing 6-3    Extracting and editing items from a picture
  10166.  
  10167. gxShape            *extractedShapes;
  10168.  
  10169. long            numberOfItems;
  10170. .
  10171. .
  10172. .
  10173. numberOfItems = GXGetPicture(housePicture, nil, nil, nil, nil);
  10174. extractedShapes = (gxShape *) 
  10175.                         NewPtr(numberOfItems * sizeof(gxShape));
  10176. GXGetPicture(housePicture, extractedShapes, nil, nil, nil);
  10177.  
  10178. GXMoveShape(extractedShapes[2], ff(-40), 0);
  10179.  
  10180. GXDrawShape(housePicture);
  10181. The code in Listing 6-3 includes two new variable declarations: a pointer to shape references and a long integer. The code in this listing calls the GXGetPicture function to determine the number of items in the house picture, uses that number to allocate enough memory to store the appropriate number of shape references, and then calls the GXGetPicture function a second time to copy the shape references from the items of the picture into the array of shape references. The sample code then uses the GXMoveShape function to move the third shape in the picture 40 grid points to the left. Notice that the extractedShapes array does not contain copies of the shapes in the picture; instead, it contains copies of references to the shapes in the picture. The references in the extractedShapes array reference the actual shapes in the picture. Therefore, moving the shape referenced by the third item in the extractedShapes array actually affects the house picture, as shown in Figure 6-19.
  10182. Figure 6-19    A picture of a house with a relocated door
  10183.  
  10184. For more information about the GXGetPicture and GXSetPicture functions, see page 6-52 through page 6-55.
  10185. Adding Items to a Picture
  10186.  
  10187. Once you have created a picture shape, you can add more items to it using one of these methods:
  10188. n    You can use the GXGetPicture function to obtain arrays of references to the shapes, overriding styles, overriding inks, and overriding transforms that make up the items of a picture. You can then add new references to these arrays and use the GXSetPicture function to replace the original items with the information in the edited arrays.
  10189. n    You can use the GXSetPictureParts function to insert any number of new items directly into a picture shape. With this function, you can insert the new items anywhere in the existing item list.
  10190. n    You can use the AddToPicture library function to insert a single new item at the end of a picture shape’s item list.
  10191. Listing 6-4 and Listing 6-5 show how to use the GXSetPictureParts function to add three new items to the house picture defined in Listing 6-1 on page 6-23. Listing 6-4 defines three new shapes to include in the picture, and Listing 6-5 uses the GXSetPictureParts function to insert the shapes into the house picture.
  10192. Listing 6-4    Defining new shapes for the house picture
  10193.  
  10194.     gxShape             lawnPolygon;
  10195.     gxShape             walkwayPolygon;
  10196.     gxShape             chimneyRectangle;
  10197.  
  10198.     . . .
  10199.     
  10200.     const long lawnGeometry[] = {1,  /* number of contours */
  10201.                                            5,  /* number of points */
  10202.                                             0x70000000, /* control bits */
  10203.                                                ff(20), ff(160),   /* on  */
  10204.                                            ff(20), ff(130),                             /* off */
  10205.                                            ff(140), ff(100),                             /* off */
  10206.                                            ff(260), ff(130),                             /* off */
  10207.                                            ff(260), ff(160)}; /* on  */
  10208.  
  10209.     const long walkwayGeometry[] = {1,  /* number of contours */
  10210.                                               3,  /* number of points */
  10211.                                               ff(102), ff(160),
  10212.                                               ff(122), ff(100),
  10213.                                               ff(142), ff(160)};
  10214.     
  10215.     gxRectangle chimneyGeometry = {ff(110), ff(50),
  10216.                                                   ff(120), ff(80)};
  10217.                                           
  10218.  
  10219.     lawnPolygon = GXNewPaths((gxPaths *) lawnGeometry);
  10220.     SetShapeCommonColor(lawnPolygon, light + gxGray);
  10221.  
  10222.     walkwayPolygon = GXNewPolygons((gxPolygons *) walkwayGeometry);
  10223.     SetShapeCommonColor(walkwayPolygon, dark + gxGray);
  10224.  
  10225.     chimneyRectangle = GXNewRectangle(&chimneyGeometry);
  10226.     SetShapeCommonColor(chimneyRectangle, dark + gxGray);
  10227. The sample code from Listing 6-4 defines a lawn shape, a walkway shape, and a chimney shape. The sample code in Listing 6-5 creates an array to store references to these three shapes, and then calls the GXSetPictureParts function to insert the shapes into the house picture.
  10228. Listing 6-5    Adding new shapes to the house picture
  10229.  
  10230.     gxShape            insertedShapes[3];
  10231.  
  10232.     .    .    .
  10233.     insertedShapes[0] = lawnPolygon;
  10234.     insertedShapes[1] = walkwayPolygon;
  10235.     insertedShapes[2] = chimneyRectangle;
  10236.     
  10237.     GXSetPictureParts(housePicture, 
  10238.                               1,      /* insert before first item */
  10239.                               0,      /* don’t replace any existing items */
  10240.                               3,      /* insert three new items */
  10241.                               insertedShapes,   /* shapes to insert */
  10242.                               nil, nil, nil);   /* no overrides */
  10243.     
  10244. The first parameter to the GXSetPictureParts function specifies the picture whose item list you want to edit. The second parameter specifes where you want the editing to occur. In this example, the second parameter is set to 1, which indicates that the new items should be inserted before the first item of the picture. QuickDraw GX draws the items of a picture in order from back to front; therefore, inserting the new items before the existing items ensures that the new items are drawn behind the existing ones.
  10245. The third parameter to the GXSetPictureParts function specifies how many of the original picture items to remove. In this example, this parameter is set to 0. For examples of removing and replacing picture items, see the next section.
  10246. The fourth parameter to the GXSetPictureParts function specifies how many new items to insert into the picture, which in this case is 3.
  10247. The last four parameters to the GXSetPictureParts function specify the shapes, overriding styles, overriding inks, and overriding transforms that make up the new picture items.
  10248. Once you have inserted the new shapes into the picture, you can dispose of the shapes (which simply lowers their owner count to 1), and then draw the picture:
  10249. GXDisposeShape(lawnPolygon);
  10250. GXDisposeShape(walkwayPolygon);
  10251. GXDisposeShape(chimneyRectangle);
  10252.  
  10253. GXDrawShape(housePicture);
  10254. The resulting picture is shown in Figure 6-20
  10255. Figure 6-20    A house with a lawn, walkway, and chimney
  10256.  
  10257. For information about the GXSetPictureParts function, see page 6-57.
  10258. Removing and Replacing Items in a Picture
  10259.  
  10260. You can use the GXSetPicture function or the GXSetPictureParts function to replace items in a picture.
  10261. The GXSetPicture function removes every item in a picture and inserts a new list of items. The GXSetPictureParts function allows you more control in replacing items. With this function, you can replace a subset of the items in a picture with another set of items. The inserted set does not have to have the same number of items as the replaced set.
  10262. As a simple example, you can use the GXSetPictureParts function to remove a single item from a picture. Listing 6-6 shows how to use the GXSetPictureParts function to remove the chimney, which is item number 3, from the house picture shown in Figure 6-20.
  10263. Listing 6-6    Removing an item from a picture
  10264.  
  10265. GXSetPictureParts(housePicture, 
  10266.                         3,   /* start editing at item 3 */
  10267.                         1,   /* remove 1 item */
  10268.                         0,   /* insert 0 items */
  10269.                         nil, /* no shapes to insert */
  10270.                         nil, nil, nil); /* no overrides */
  10271. This call to the GXSetPictureParts function removes one item starting with item 3, which is the chimney. The resulting picture is shown in Figure 6-21.
  10272. Figure 6-21    A house with chimney removed 
  10273.  
  10274. You can also use the GXSetPictureParts function to replace items in a picture; with a single call to GXSetPictureParts, you can remove items from a picture and insert new items into a picture.
  10275. Like the sample code in Listing 6-6, the sample code in Listing 6-7 uses the GXSetPictureParts function to remove the chimney shape from the house picture. However, this call to the GXSetPictureParts function inserts a new chimney into the house picture at the same time.
  10276. Listing 6-7    Replacing one shape with another
  10277.  
  10278.     gxShape newChimneyRectangle;
  10279.  
  10280.     gxRectangle newChimneyGeometry = {ff(170), ff(50),
  10281.                                                        ff(180), ff(80)};
  10282.     . . .
  10283.  
  10284.     newChimneyRectangle = GXNewRectangle(&newChimneyGeometry);
  10285.     SetShapeCommonColor(newChimneyRectangle, dark + gxGray);
  10286.     
  10287.     GXSetPictureParts(housePicture, 
  10288.                             3,  /* start editing at item 3 */
  10289.                             1,  /* remove 1 item */
  10290.                             1,  /* insert 1 item */
  10291.                             &newChimneyRectangle,  /* shape to insert */
  10292.                             nil, nil, nil);          /* no overrides */
  10293.     
  10294.     GXDisposeShape(newChimneyRectangle);
  10295. The resulting house picture is shown in Figure 6-22
  10296. Figure 6-22    A house with the chimney replaced
  10297.  
  10298. For information about the GXSetPictureParts function, see page 6-57.
  10299. Overriding Styles, Inks, and Transforms
  10300.  
  10301. As detailed in the previous three sections, QuickDraw GX provides a number of methods for adding items to a picture shape. In particular, you can add items when creating a picture using the GXNewPicture function, you can replace every item in an existing picture using the GXSetPicture function, and you can replace some of the items in a picture using the GXSetPictureParts function. All three of these function allow you to specify overriding styles, inks, and transforms for the new picture items.
  10302. As an example, the code in Listing 6-8 and Listing 6-9 alters the house picture from Listing 6-1 on page 6-23. Listing 6-8 defines a style object, an ink object, and a transform object. Listing 6-9 uses these objects and the GXSetPicture function to create a house picture whose items contain overriding styles, inks, and transforms.
  10303. Listing 6-8        Creating style, ink, and transform objects
  10304.  
  10305.     gxShape squarePattern;
  10306.     gxStyle patternedStyle;
  10307.     gxInk grayInk;
  10308.     gxTransform skewedTransform;
  10309.                                   
  10310.     gxRectangle squareGeometry = {ff(0), ff(0),
  10311.                                               ff(2), ff(2)};
  10312.     gxPatternRecord                     patternRecord;
  10313.     .
  10314.     .
  10315.     .
  10316.     squarePattern = GXNewRectangle(&squareGeometry);
  10317.     patternRecord.attributes = gxNoAttributes;
  10318.     patternRecord.pattern = squarePattern;
  10319.     patternRecord.u.x = ff(1);
  10320.     patternRecord.u.y = ff(4);
  10321.     patternRecord.v.x = ff(3);
  10322.     patternRecord.v.y = ff(1);
  10323.     
  10324.     patternedStyle = GXNewStyle();
  10325.     GXSetStylePattern(patternedStyle, &patternRecord);
  10326.     
  10327.     grayInk = GXNewInk();
  10328.     SetInkCommonColor(grayInk, gxGray);
  10329.  
  10330.     skewedTransform = GXNewTransform();
  10331.     GXSkewTransform(skewedTransform, -fl(.5), 0, ff(122), ff(110));
  10332. Listing 6-9 uses the style, ink, and transform objects defined in Listing 6-8, and the partsOfHouse array (which is defined in Listing 6-1 on page 6-23) to create a house picture. In this house picture, the main part of the house has an overriding style, the roof has an overriding ink, and the door has an overriding transform.
  10333. Listing 6-9    Creating a picture whose items have overriding styles, inks, and transforms
  10334.  
  10335. gxStyle          overridingStyles[3];
  10336. gxInk          overridingInks[3];
  10337. gxTransform     overridingTransforms[3];
  10338. .
  10339. .
  10340. .
  10341. overridingStyles[0] = patternedStyle;
  10342. overridingStyles[1] = nil;
  10343. overridingStyles[2] = nil;
  10344.  
  10345. overridingInks[0] = nil;
  10346. overridingInks[1] = grayInk;
  10347. overridingInks[2] = nil;
  10348.  
  10349. overridingTransforms[0] = nil;
  10350. overridingTransforms[1] = nil;
  10351. overridingTransforms[2] = skewedTransform;
  10352.     
  10353. housePicture = GXNewShape(gxPictureType);
  10354. GXSetPicture(housePicture, 
  10355.                  3, 
  10356.                  partsOfHouse, 
  10357.                  overridingStyles, 
  10358.                  overridingInks, 
  10359.                  overridingTransforms);
  10360. Once you have added the overriding style, ink, and transform objects to the picture, you can dispose of them, as shown in Listing 6-10. Since these objects are referenced twice (once by your application and once by the house picture), disposing of them lowers their owner counts to 1, but does not free the memory associated with them. When you eventually dispose of the house picture, QuickDraw GX disposes of these objects again and frees their memory.
  10361. Listing 6-10    Disposing of overriding style, ink, and transform objects before drawing
  10362.  
  10363. GXDisposeShape(squarePattern);
  10364. GXDisposeStyle(patternedStyle);
  10365. GXDisposeInk(grayInk);
  10366. GXDisposeTransform(skewedTransform);
  10367.  
  10368. GXDrawShape(housePicture);
  10369. The resulting picture is shown in Figure 6-23.
  10370. Figure 6-23    A house picture with an overriding style, ink, and transform
  10371.  
  10372. For more information about overriding styles, inks, and transforms, see “Overriding Styles, Inks, and Transforms” beginning on page 6-7.
  10373. For more information about the GXNewPicture function, see page 6-50. For more information about the GXSetPicture function, see page 6-53.
  10374. Adding Multiple References 
  10375.  
  10376. Multiple items in a single picture can reference the same shape. You can use any of the functions that add items to a picture (GXNewPicture, GXSetPicture, GXSetPictureParts) to add multiple references to a single shape. The example in Listing 6-11 adds four new items to the house picture defined in Listing 6-1 on page 6-23. Each of these items references the same shape—a small, white rectangle. Because four items reference the same rectangle, four instances of this rectangle appear in the picture. Without overriding transforms, however, all four instances of this rectangle would appear in the same location. Therefore, the sample code in Listing 6-11 creates overriding transforms for three of the four new items.
  10377. Listing 6-11    Adding four items to a house picture that reference the same shape
  10378.  
  10379. gxRectangle windowGeometry = {ff(155), ff(93),
  10380.                                           ff(160), ff(112)};
  10381.                                   
  10382. gxShape windowRectangle;
  10383.     
  10384. gxShape insertedShapes[4];
  10385. gxTransform overridingTransforms[4];
  10386.     
  10387. windowRectangle = GXNewRectangle(&windowGeometry);
  10388. SetShapeCommonColor(windowRectangle, gxWhite);
  10389.     
  10390. insertedShapes[0] = windowRectangle;
  10391. insertedShapes[1] = windowRectangle;
  10392. insertedShapes[2] = windowRectangle;
  10393. insertedShapes[3] = windowRectangle;
  10394.     
  10395. overridingTransforms[0] = nil;
  10396. overridingTransforms[1] = GXNewTransform();
  10397. overridingTransforms[2] = GXNewTransform();
  10398. overridingTransforms[3] = GXNewTransform();
  10399.  
  10400. GXMoveTransform(overridingTransforms[1], ff(7), 0);
  10401. GXMoveTransform(overridingTransforms[2], ff(14), 0);
  10402. GXMoveTransform(overridingTransforms[3], ff(21), 0);
  10403.     
  10404. GXSetPictureParts(housePicture, 
  10405.                        3,  /* where to insert */
  10406.                        0,  /* how many to replace */
  10407.                        4,  /* how many to insert */
  10408.                        insertedShapes, 
  10409.                        nil, nil, 
  10410.                        overridingTransforms);
  10411. This sample code creates one rectangle shape and three transform objects. Once you insert these objects into the picture, you can dispose of them to lower their owner count to 1, as shown in Listing 6-12. Since these objects are referenced twice (once by your application and once by the house picture), disposing of them lowers their owner counts to 1, but does not free the memory associated with them. When you dispose of the house picture, QuickDraw GX disposes of these objects again and frees their memory.
  10412. Listing 6-12    Disposing of the white rectangle and the three transform objects before drawing
  10413.  
  10414. int count;
  10415. .
  10416. .
  10417. .
  10418. for (count = 1; count <= 3 ; count++)
  10419.     GXDisposeTransform(overridingTransforms[count]);
  10420.          
  10421. GXDisposeShape(windowRectangle);
  10422.         
  10423. GXDrawShape(housePicture);
  10424. The resulting picture is shown in Figure 6-24.
  10425. Figure 6-24    A house with four windows
  10426.  
  10427. Notice that the sample code in Listing 6-12 creates three separate transform objects because three different transformations are happening to the instances of the window rectangle—the second instance is moved 7 grid points to the right, the third instance is moved 14 grid points to the right, and the fourth instance is moved 21 grid points to the right. 
  10428. You can specify that QuickDraw GX copy the overriding transforms when adding them to the picture (rather than adding them by reference) by setting the unique items shape attribute, as discussed in the next section.
  10429. For more information about adding multiple items referencing the same shape, see “Multiple References” beginning on page 6-9.
  10430. Adding Unique Items
  10431.  
  10432. The unique items shape attribute changes the way in which QuickDraw GX adds shapes to a picture. When you add a shape to a picture that does not have this attribute set, QuickDraw GX copies the reference to the existing shape, inserts this reference into the picture’s item list, and increments the owner count of the shape. Similarly, if you specify an overriding style, ink, or transform object for the shape, QuickDraw GX copies the object’s reference into the picture’s item list and increments the owner count of the object.
  10433. However, when you add a shape to a picture that has the unique items attribute set, QuickDraw GX makes a copy of the shape and inserts a reference to the copy into the picture’s item list. Similarly, overriding styles, inks, and transforms are also copied.
  10434. As an example, Listing 6-13 shows how to use the GXGetShapeAttributes and GXSetShapeAttributes functions to set the unique items shape attribute of a picture. You must set this attribute before you add any items to a picture; if the picture already contains items, setting this attribute results in an error.
  10435. This listing adds four instances of a window rectangle to the house picture from 
  10436. Listing 6-1. This sample code specifies the same overriding transform for each instance of the window rectangle. However, the overriding transform is moved (with the GXMoveTransform function) after each call to the AddToPicture function. Because the house picture has the unique items shape attribute set, QuickDraw GX makes a separate copy of the overriding transform each time a window rectangle is inserted into the picture.
  10437. Listing 6-13    Adding unique items to a picture 
  10438.  
  10439. GXSetShapeAttributes(housePicture,
  10440.     GXGetShapeAttributes(housePicture) | gxUniqueItemsShape);
  10441. .
  10442. .
  10443. .
  10444. moveToRight = GXNewTransform();
  10445.  
  10446. for (count = 0; count <= 3 ; count++) {
  10447.     AddToPicture(housePicture, 
  10448.                      windowRectangle, 
  10449.                      nil, nil, 
  10450.                      moveToRight);
  10451.     GXMoveTransform(moveToRight, ff(7), 0);
  10452. }
  10453. In this example, the first time that the AddToPicture function is called, QuickDraw GX creates a copy of the window rectangle shape and a copy of the overriding transform object, and inserts references to the copies into the item list of the house picture. 
  10454. The second time that the AddToPicture function is called, QuickDraw GX notices that the window rectangle shape has not changed, so it does not make another copy of the window rectangle. Instead, it creates a new item in the house picture that references the previously made copy. However, the overriding transform has changed, so QuickDraw GX makes a new copy of it for the new picture item.
  10455. The third and fourth calls to the AddToPicture function also create new copies of the overriding transform, but do not create new copies of the window rectangle.
  10456. After the code from Listing 6-13 finishes executing, there are a total of two window rectangles—the original one, which is referenced by the windowRectangle variable, and the copy, which is referenced four times by the items of the house picture. There are a total of five transform objects—the original one, which is referenced by the moveToRight variable, and four separate copies referenced by the four new items of the picture.
  10457. Figure 6-25 shows the resulting picture.
  10458. Figure 6-25    A house with four windows and four unique overriding transforms
  10459.  
  10460. For more information about the unique items shape attribute, see “Unique Items Attribute” beginning on page 6-13.
  10461. Creating Picture Hierarchies
  10462.  
  10463. QuickDraw GX allows the items in a picture shape to reference other picture shapes. You can use any of the functions that allow you to add items to pictures (GXNewPicture, GXSetPicture, GXSetPictureParts) to create picture hierarchies.
  10464. When drawing a picture hierarchy, QuickDraw GX concatenates the mapping and clipping information contained in the transform objects (or overriding transform objects) at each level of the hierarchy. As an example, Listing 6-14 shows how QuickDraw GX concatenates mapping information from two levels of a picture hierarchy. In this example, the house picture from Figure 6-20 on page 6-30 is added to another picture as an item with an overriding transform that rotates the house clockwise 90 degrees. In turn, this picture is added as an item to yet another picture, with the same overriding transform.
  10465. Listing 6-14        Creating a picture hierarchy
  10466.  
  10467. gxShape rootPicture, level1Picture;
  10468. gxTransform rotateHouse;
  10469. .
  10470. .
  10471. .
  10472. rotateHouse = GXNewTransform();
  10473. GXRotateTransform(rotateHouse, ff(90), ff(150), ff(100));
  10474.     
  10475. level1Picture =  GXNewPicture(1, 
  10476.                                        &housePicture, 
  10477.                                         nil, nil, 
  10478.                                         &rotateHouse);
  10479. rootPicture = GXNewPicture(1, 
  10480.                                     &level1Picture, 
  10481.                                     nil, nil, 
  10482.                                     &rotateHouse);
  10483.  
  10484. GXDrawShape(rootPicture);
  10485. When QuickDraw GX draws the root-level picture, it concatenates the information in the two overriding transforms, and draws the house picture rotated clockwise 180 degrees, as shown in Figure 6-26.
  10486. Figure 6-26    A house rotated by 90 degrees two times
  10487.  
  10488. For more information about picture hierarchies and transform concatenation, see “Picture Hierarchies” beginning on page 6-14 and “Transform Concatenation” beginning on page 6-15. 
  10489. Hit-Testing Pictures
  10490.  
  10491. As described in “Hit-Testing Picture Shapes” beginning on page 6-20, QuickDraw GX hit-tests a picture shape by
  10492. n    hit-testing each item contained in the picture, using the hit-test information in that item’s transform object (or overriding transform object, if the item has one)
  10493. n    compiling a list of items that were hit
  10494. n    selecting one of the items using criteria you provide
  10495. n    providing information about the selected item that was hit
  10496. The criteria you specify includes the depth at which you want to hit-test the picture, and the level of the picture hierarchy at which you want to hit-test.
  10497. To illustrate picture hit-testing, Listing 6-15 creates a picture hierarchy using the shapes defined in Listing 6-1 on page 6-23 and Listing 6-4 on page 6-28. This example creates a picture shape that contains two items. The first item is a picture of a lawn and a walkway, and the second item is a picture of a chimney, house, roof, and door.
  10498. Listing 6-15    Creating a picture hierarchy
  10499.  
  10500. gxShape            groundsPicture, housePicture, entirePicture;
  10501.     
  10502. gxShape            partsOfHouse[4];
  10503. gxShape            partsOfGrounds[2];
  10504. gxShape            partsOfEntirePicture[2];
  10505. .
  10506. .
  10507. .
  10508. partsOfGrounds[0] = lawnPolygon;
  10509. partsOfGrounds[1] = walkwayPolygon;
  10510. groundsPicture = GXNewPicture(2, partsOfGrounds, nil, nil, nil);
  10511.  
  10512. partsOfHouse[0] = chimneyRectangle;
  10513. partsOfHouse[1] = houseRectangle;
  10514. partsOfHouse[2] = roofPolygon;
  10515. partsOfHouse[3] = doorRectangle;
  10516. housePicture = GXNewPicture(4, partsOfHouse, nil, nil, nil);
  10517.     
  10518. partsOfEntirePicture[0] = groundsPicture;
  10519. partsOfEntirePicture[1] = housePicture;
  10520. entirePicture = GXNewPicture(2, partsOfEntirePicture, 
  10521.                                       nil, nil, nil);
  10522. Figure 6-27 shows the items that make up the grounds picture.
  10523. Figure 6-27    Grounds picture
  10524.  
  10525. Figure 6-28 shows the items that make up the house picture.
  10526. Figure 6-28    House picture
  10527.  
  10528. Figure 6-29 shows the entire picture created in Listing 6-15.
  10529. Figure 6-29    Picture containing grounds picture and house picture
  10530.  
  10531. You hit-test a picture shape using the function GXHitTestPicture. This function takes as its parameters a reference to the picture to hit-test, the test point, an optional hit-test parameters structure, the level at which to hit-test, and the depth at which to hit-test. The sample code in Listing 6-16 shows how to hit-test the picture from Listing 6-15 using a test point of ff(122), ff(110).
  10532. Listing 6-16    Hit-testing a picture shape
  10533.  
  10534. gxPoint testPoint = {ff(122), ff(110)};
  10535. gxShape hitShape;
  10536. long level, depth;
  10537. .
  10538. .
  10539. .
  10540. hitShape = GXHitTestPicture(entirePicture, &testPoint, nil,         
  10541.                                      level, depth);
  10542. Figure 6-30 shows the location of the test point.
  10543. Figure 6-30    Hit-testing the picture of house and grounds
  10544.  
  10545. The GXHitTestPicture function returns a reference to the shape that was hit by the test point. In this example, the test point falls above four separate shapes: the door rectangle, the house rectangle, the walkway polygon, and the lawn path. By varying the values of the level and depth parameters, you can control which shape is returned by the GXHitTestPicture function.
  10546. Table 6-1 shows which shape is returned for various choices of level and depth.
  10547. Table 6-1    Hit-testing a picture at different levels and depths
  10548. Level    Depth    Hit Shape    
  10549. 2    1    Door rectangle    
  10550. 1    1    House picture    
  10551. 2    2    House rectangle    
  10552. 1    2    House picture    
  10553. 2    3    Walkway polygon    
  10554. 1    3    Grounds picture    
  10555. 2    4    Lawn path    
  10556. 1    4    Grounds picture    
  10557.  
  10558. At depth 1, the returned shape is the frontmost shape that was hit—in this case, the door rectangle, which is at level 2 in the picture hierarchy. If you specify a depth of 1 and a level of 1, the GXHitTestPicture function returns the picture that contains the door rectangle—in this case the house picture.
  10559. In a similar manner, depth 2 indicates the house rectangle, depth 3 indicates the walkway polygon, and depth 4 indicates the lawn path.
  10560. For information about the GXHitTestPicture function, see page 6-60.
  10561.  
  10562.  
  10563. Applying Functions Described Elsewhere to Picture Shapes
  10564.  
  10565. QuickDraw GX provides only a small number of functions that apply exclusively to picture shapes. However, many of the QuickDraw GX functions that you can apply to other types of shapes you can also apply to picture shapes. 
  10566. The next six sections discuss how functions described elsewhere operate when applied to picture shapes. These sections are
  10567. n    “Functions That Post Errors or Warnings” beginning on page 6-46, which lists functions that you can apply to other types of shapes but not to picture shapes.
  10568. n    “Shape-Related Functions” beginning on page 6-47, which lists functions that operate on picture shape objects.
  10569. n    “Geometric Operations” beginning on page 6-48, which lists the few geometric operation functions that you can apply to pictures.
  10570. n    “Style-Related Functions” beginning on page 6-49, which discusses how style-related functions apply to pictures.
  10571. n    “Ink- and Color-Related Functions” beginning on page 6-49, which discusses how ink-related functions apply to pictures.
  10572. n    “Transform- and View-Related Functions” beginning on page 6-49, which discusses how transform-related functions apply to pictures. 
  10573. Functions That Post Errors or Warnings
  10574.  
  10575. Some QuickDraw GX functions that operate on other types of shapes do nothing but post an error or a warning if you try to apply them to a picture shape.
  10576. For example, there are a number of shape-related functions and geometric operations that you cannot apply to picture shapes. Table 6-2 lists these functions, which are described in full in Chapter 2, “Geometric Shapes,” and Chapter 4, “Geometric Operations.”
  10577. Table 6-2    Geometric operations that post errors or warnings when applied to pictures
  10578. Function name    Error or warning posted    
  10579. GXBreakShape    graphic_type_does_not_contain_points    
  10580. GXContainsShape    shape_operator_may_not_be_a_picture    
  10581. GXCountShapePoints    graphic_type_does_not_contain_points    
  10582. GXDifferenceShape    shape_operator_may_not_be_a_picture    
  10583. GXExcludeShape    shape_operator_may_not_be_a_picture    
  10584. GXGetShapeCenter    illegal_type_for_shape    
  10585. GXGetShapeDirection    graphic_type_does_not_have_multiple_contours    
  10586. GXGetShapeLength    shape_does_not_have_length    
  10587. GXGetShapePoints    graphic_type_does_not_contain_points    
  10588. GXInsetShape    graphic_type_cannot_be_inset    
  10589. GXIntersectShape    shape_operator_may_not_be_a_picture    
  10590. GXInvertShape    shape_cannot_be_inverted    
  10591. GXReverseDifferenceShape    shape_operator_may_not_be_a_picture    
  10592. GXReverseShape    contour_out_of_range    
  10593. GXShapeLengthToPoint    shape_does_not_have_length    
  10594. GXSetShapePoints    graphic_type_does_not_contain_points    
  10595. GXTouchesShape    shape_operator_may_not_be_a_picture    
  10596. GXUnionShape    shape_operator_may_not_be_a_picture    
  10597.  
  10598. Most of these geometric operations do not apply to picture shapes because a picture’s geometry is substantially different from the geometry of a geometric shape. 
  10599. You can apply a few of the geometric operations to pictures, however. These functions are discussed in “Geometric Operations” beginning on page 6-48.
  10600. Shape-Related Functions 
  10601.  
  10602. You can apply all of the functions described in the “Shape Objects” chapter of Inside Macintosh: QuickDraw GX Objects to picture shapes. These functions allow you to
  10603. n    manipulate the shape object that represents the picture shape; for example, you can copy, clone, cache, compare, and dispose of the picture shape.
  10604. n    set the geometry, shape type, shape fill, and shape attributes of the picture shape
  10605. n    change the style, ink, and transform objects that are associated with the picture shape
  10606. n    manipulate the picture shape’s tags and owner count
  10607. Table 6-3 gives important picture-related information for a subset of the functions from the chapter “Shape Objects” of Inside Macintosh: QuickDraw GX Objects. Functions described in that chapter that do not appear in this list exhibit the same behavior when applied to picture shapes as they do when applied to other types of shapes.
  10608. Table 6-3    Shape-related functions that exhibit special behavior when applied to pictures
  10609. Function name    Action taken    
  10610. GXCopyToShape    Makes a copy of the picture shape; the items of the new picture shape reference the same shapes as the items of the original picture shape.    
  10611. GXCopyDeepToShape    Makes a copy of the picture shape, including a complete copy of the entire picture hierarchy.    
  10612. GXGetShapeSize    Determines the amount of memory currently used by all of the items in the picture.    
  10613. GXGetShapeFill    Returns the shape’s shape fill, which for picture shapes is always even-odd (solid) fill or no fill.    
  10614. GXSetShapeFill    Sets the shape’s shape fill; you must always set a picture shape’s shape fill to even-odd (solid) fill or no fill.    
  10615. GXSetShapeType    Changes the shape type of the picture shape and converts the shape fill and geometry as appropriate. The resulting shape is a picture with one item—the original shape.     
  10616.  
  10617. Geometric Operations
  10618.  
  10619. Many geometric operations post errors or warnings when applied to picture shapes, as described in “Functions That Post Errors or Warnings” on page 6-46.
  10620. You can, however, apply the remainder of the functions described in Chapter 4, “Geometric Operations,” to picture shapes. Table 6-1 gives important picture-related information for a subset of these functions; the remainder of the geometric operations exhibit the same behavior when applied to picture shapes as they do when applied to other types of shapes.
  10621. Table 6-4    Geometric operations that exhibit special behavior when applied to pictures
  10622. Function name    Action taken    
  10623. GXGetShapeArea    Returns summed areas of picture items.    
  10624. GXGetShapeBounds    Returns bounding rectangle of specified item.    
  10625. GXSetShapeBounds    If the picture’s mapTransformShape shape attribute is set, this function changes the picture’s transform so that the entire picture fits within the specifed bounding rectangle. If this attribute is not set, this function posts an error.    
  10626.  
  10627. Style-Related Functions
  10628.  
  10629. Picture shapes make limited use of their style objects. You may apply to a picture shape any of the functions described in Chapter 3, “Geometric Styles,” (such as GXSetShapePen, GXSetShapeDash, and so on) to set the properties of a picture’s style object, and you may use the corresponding functions (GXGetShapePen, GXGetShapeDash, and so on) to examine these properties. However, QuickDraw GX ignores these properties when drawing a picture.
  10630. Ink- and Color-Related Functions
  10631.  
  10632. Picture shapes make limited use of their ink objects. You may apply to a picture shape any of the shape-related functions described in the chapter “Ink Objects” of Inside Macintosh: QuickDraw GX Objects. (such as GXSetShapeColor, GXSetShapeTransfer) to set the other properties of a picture’s ink object, and you may use the corresponding functions (GXGetShapeColor, GXGetShapeTransfer) to examine these properties. However, QuickDraw GX ignores these properties when drawing a picture.
  10633. Transform- and View-Related Functions 
  10634.  
  10635. Although picture shapes do not make full use of their style and ink objects, they do make full use of their transform objects. You can apply all of the shape-related functions that are described in the chapter “Transform Objects” of Inside Macintosh: QuickDraw GX Objects, to picture shapes. 
  10636. In general, you need to be sure that a picture shape’s mapTransformShape shape attribute is set before applying any of the mapping operations to a picture.
  10637.  
  10638.  
  10639. Picture Shapes Reference
  10640.  
  10641. Functions
  10642.  
  10643. This section describes the functions provided by QuickDraw GX specifically for creating and manipulating picture shapes. With the functions described in this section, you can
  10644. n    create a new picture shape
  10645. n    examine and edit the items of a picture shape
  10646. n    draw pictures
  10647. n    hit-test pictures
  10648. See the section “Applying Functions Described Elsewhere to Picture Shapes” beginning on page 6-46 for information about other QuickDraw GX functions that you can apply to picture shapes.
  10649. Creating Picture Shapes
  10650.  
  10651. This section describes the GXNewPicture function, which you use to create new picture shapes.
  10652. GXNewPicture 
  10653.  
  10654. You can use the GXNewPicture function to create a new picture shape.
  10655. gxShape GXNewPicture(long count, const gxShape shapes[], 
  10656.                             const gxStyle styles[], const gxInk inks[],
  10657.                             const gxTransform transforms[])
  10658. count    The number of picture items in the new picture shape.
  10659. shapes    An array of references to the shapes you want to include in the picture.
  10660. styles    An array of references to the style objects you want to use as overriding styles for the picture items. You may provide nil for this parameter if you do not want any overriding styles.
  10661. inks    An array of references to the ink objects you want to use as overriding inks for the picture items. You may provide nil for this parameter if you do not want any overriding inks.
  10662. transforms    An array of references to the transform objects you want to use as overriding transforms for the picture items. You may provide nil for this parameter if you do not want any overriding transforms.
  10663. function result    A reference to the newly created picture shape.
  10664. DESCRIPTION
  10665. The GXNewPicture function creates a new picture shape.
  10666. In the count parameter, you specify the number of shapes you want to include as items of the picture, and in the shapes parameter, you provide references to the shapes. 
  10667. In the styles parameter, you specify references to overriding styles. Each item of this array overrides the style of the corresponding shape in the shapes array. For example, the first style you provide in the styles array becomes the overriding style for the first shape in the shapes array, and so on. Similarly, in the inks and transforms parameters you specify references to overriding inks and transforms. 
  10668. You may specify 0 for the count parameter and nil for the shapes, styles, inks, and transforms parameters to create an empty picture—a picture containing no picture items. You may provide nil for the styles, inks, or transforms parameters even if you provide shape references in the shapes parameter. In this case, the newly created picture shape contains picture items, but those items contain no overriding styles, inks, or transforms, respectively.
  10669. You may also provide nil for an individual item of a styles, inks, or transforms array if you do not want the corresponding picture item to have an overriding style, ink, or transform.
  10670. SPECIAL CONSIDERATIONS
  10671. If no error results, the GXNewPicture function creates a picture shape; you are responsible for disposing of this shape when you no longer need it. See Inside Macintosh: QuickDraw GX Objects for information about creating and disposing of shapes.
  10672. RESULT CODESErrors    
  10673. out_of_memory    
  10674. parameter_is_nil    
  10675. shape_is_nil    
  10676. parameter_out_of_range    
  10677.  
  10678. SEE ALSO
  10679. For information about picture items and their overriding styles, inks, and transforms, see “About Picture Shapes” beginning on page 6-3.
  10680. For an example of this function, see “Creating and Drawing Picture Shapes” beginning on page 6-22.
  10681. To draw a picture shape once you’ve created one, use the GXDrawShape function, described in the chapter “Shape Objects” of Inside Macintosh: QuickDraw GX Objects. Inside
  10682. For information about disposing of picture shapes, see the description of the GXDisposeShape function, which is in the chapter “Shape Objects” of Inside Macintosh: QuickDraw GX Objects.
  10683. Getting and Setting Picture Geometries
  10684.  
  10685. This section describes the functions you can use to examine or replace the entire geometry of a picture shape—that is, all of the picture items included in the picture.
  10686. The GXGetPicture function provides references to the shapes contained in a picture geometry and references to their overriding styles, inks, and transforms.
  10687. The GXSetPicture function replaces references to the shapes contained in a picture geometry and references to their overriding styles, inks, and transforms.
  10688. GXGetPicture  
  10689.  
  10690. You can use the GXGetPicture function to obtain references to the shapes contained in a picture and references to their overriding styles, inks, and transforms.
  10691. long GXGetPicture(gxShape source, gxShape shapes[], 
  10692.                         gxStyle styles[], gxInk inks[], 
  10693.                         gxTransform transforms[]);
  10694. source    A reference to the picture shape whose items you want to examine.
  10695. shapes    An array of shape references. On output, this array contains references to the shapes contained in the source picture. 
  10696. styles    An array of references to style objects. On output, this array contains references to the overriding styles contained in the source picture.
  10697. inks    An array of references to ink objects. On output, this array contains references to the overriding inks contained in the source picture.
  10698. transforms    An array of references to transform objects. On output, this array contains references to the overriding transforms contained in the source picture.
  10699. function result    The total number of items in the source picture.
  10700. DESCRIPTION
  10701. If you provide arrays for the shapes, styles, inks, and transforms parameters, this function copies the references to shapes, styles, inks, and transforms from the picture’s geometry into these arrays. However, you may provide nil for any of these parameters to indicate that you do not want to obtain the corresponding references. 
  10702. Typically, you call this function twice. The first time you specify nil for all of the array parameters and use the function result to determine the number of picture items, which you can use to allocate arrays large enough to contain the shape, style, ink, and transform references. Then you call the function a second time to determine the actual references.
  10703. RESULT CODESErrors    
  10704. out_of_memory    
  10705. shape_is_nil    
  10706. illegal_type_for_shape    
  10707.  
  10708. SEE ALSO
  10709. For information about picture items and their overriding styles, inks, and transforms, see “About Picture Shapes” beginning on page 6-3.
  10710. For an example of this function, see “Getting and Setting Picture Geometries” beginning on page 6-26.
  10711. To examine a subset of the items in a picture geometry, use the GXGetPictureParts function, which is described on page 6-55.
  10712. To replace the information in the geometry of a picture shape, use the GXSetPicture function, which is described in the next section.
  10713. GXSetPicture  
  10714.  
  10715. You can use the GXSetPicture function to replace the information in the geometry of a picture shape.
  10716. void GXSetPicture(gxShape target, long count, 
  10717.                         const gxShape shapes[], const gxStyle styles[],
  10718.                         const gxInk inks[], 
  10719.                         const gxTransform transforms[]);
  10720. target    A reference to the picture shape whose geometry you want to replace.
  10721. count    The number of picture items in the new picture geometry.
  10722. shapes    An array of references to the shapes to include in the new picture geometry.
  10723. styles    An array of references to the styles you want to use as overriding styles in the new picture geometry. You may provide nil for this parameter if you do not want any overriding styles.
  10724. inks    An array of references to the inks you want to use as overriding inks in the new picture geometry. You may provide nil for this parameter if you do not want any overriding inks.
  10725. transforms    An array of references to the transforms you want to use as overriding transforms in the new picture geometry. You may provide nil for this parameter if you do not want any overriding transforms.
  10726. DESCRIPTION
  10727. The GXSetPicture function replaces the geometry of the picture shape object referenced by the target parameter with a new geometry. To maintain correct owner counts, this function disposes of the shapes, styles, inks, and transforms referenced by the items of the original picture geometry.
  10728. In the count parameter, you specify the number of shapes in the new picture geometry, and in the shapes parameter you provide references to the shapes. 
  10729. In the styles parameter, you specify references to the styles to use as overriding styles in the new picture geometry. Each item of this array overrides the style of the corresponding shape in the shapes array. For example, the first style you provide in the styles array becomes the overriding style for the first shape in the shapes array, and so on. Similarly, in the inks and transforms parameters you specify references to overriding inks and transforms. 
  10730. You may specify 0 for the count parameter and nil for the shapes, styles, inks, and transforms parameters to create an empty picture—a picture containing no picture items. You may provide nil for the styles, inks, or transforms parameters even if you provide shape references in the shapes parameter. In this case, the newly created picture shape contains picture items, but those items contain no overriding styles, inks, or transforms, respectively.
  10731. You may also provide nil for an individual item of a styles, inks, or transforms array if you do not want the corresponding picture item to have an overriding style, ink, or transform.
  10732. RESULT CODESErrors    
  10733. out_of_memory    
  10734. shape_is_nil    
  10735. inconsistent_parameters    
  10736. cannot_set_item_shapes_to_nil    
  10737. cannot_use_original_item_shapes_when_growing_picture    
  10738. illegal_type_for_shape    
  10739. Warnings    
  10740. shape_access_not_allowed    
  10741. picture_cannot_contain_itself    
  10742. cannot_dispose_default_style    
  10743. cannot_dispose_default_ink    
  10744. cannot_dispose_default_transform    
  10745. cannot_dispose_default_colorProfile    
  10746.  
  10747. SEE ALSO
  10748. For information about picture items and their overriding styles, inks, and transforms, see “About Picture Shapes” beginning on page 6-3.
  10749. To examine the items of a picture geometry, use the GXGetPicture function, which is described on page 6-52.
  10750. To replace a subset of the items in a picture geometry, use the GXSetPictureParts function, which is described on page 6-57.
  10751. For information about disposing of shapes, see the chapter “Shape Objects” of Inside Macintosh: QuickDraw GX Objects.
  10752. Editing Picture Parts
  10753.  
  10754. This section describes the functions you can use to examine and replace specific items withing a picture geometry.
  10755. The GXGetPictureParts function allows you to obtain information about a specified subset of the picture items contained in a picture geometry.
  10756. The GXSetPictureParts function allows you to replace a subset of the picture items in a picture geometry with new picture items.
  10757. GXGetPictureParts  
  10758.  
  10759. You can use the GXGetPictureParts function to obtain information about a specified subset of a picture’s items.
  10760. long GXGetPictureParts(gxShape source, long index, long count,
  10761.                               gxShape shapes[], gxStyle styles[], 
  10762.                               gxInk inks[], gxTransform transforms[])
  10763. source    A reference to the picture shape whose items you want to examine.
  10764. index    The index of the first picture items you want to examine.
  10765. count    The total number of items you want to examine. You may supply the selectToEnd constant (–1) to indicate that you want to examine all picture items (starting with the picture item indicated by the index parameter.)
  10766. shapes    An array of shape references. On output, this array contains references to the specified shapes contained in the source picture. 
  10767. styles    An array of style references. On output, this array contains references to the overriding styles corresponding to the returned shapes.
  10768. inks    An array of ink references. On output, this array contains references to the overriding inks corresponding to the returned shapes.
  10769. transforms    An array of transform references. On output, this array contains references to the overriding transforms corresponding to the returned shapes.
  10770. function result    The total number of items returned.
  10771. DESCRIPTION
  10772. The GXGetPictureParts function extracts information from a subset of the picture items in the picture shape referenced by the source parameter. You specify which picture items using the index and count parameters. The index parameter, which must have a value of 1 or greater, indicates the first picture item you want to examine. The count parameter indicates how many items you want to examine. 
  10773. You provide arrays to hold the returned information in the shapes, styles, inks, and transforms parameters. In the shapes array, the GXGetPictureParts function returns references to the shapes that correspond to picture items you specified with the index and count parameters. In the styles, inks, and transforms arrays, this function returns references to the overriding styles, inks, and transforms for the specified picture items. You may provide nil for any of the array parameters to indicate that you do not want to obtain the corresponding references. 
  10774. This function returns as its function result the number of picture items returned. Typically, this value is the same as the value you provide for the count parameter. However, if the source picture has too few items to satisfy your request, the function returns 0 as its function result and no references are returned in the array parameters.
  10775. RESULT CODESErrors    
  10776. out_of_memory    
  10777. shape_is_nil    
  10778. illegal_type_for_shape    
  10779.  
  10780. SEE ALSO
  10781. For information about picture items and their overriding styles, inks, and transforms, see “About Picture Shapes” beginning on page 6-3.
  10782. To examine all of the items in a picture geometry, use the GXGetPicture function, which is described on page 6-52.
  10783. To replace a subset of the items in a picture geoemtry, use the GXSetPictureParts function, which is described in the next section.
  10784. GXSetPictureParts  
  10785.  
  10786. You can use the GXSetPictureParts function to add, remove, or replace a range of picture items in a picture shape’s geometry.
  10787. void GXSetPictureParts(gxShape target, long index, long oldCount,
  10788.                               long newCount, const gxShape shapes[],
  10789.                               const gxStyle styles[], 
  10790.                               const gxInk inks[], 
  10791.                               const gxTransform transforms[]);
  10792. target    A reference to the picture shape whose picture item list you want to alter.
  10793. index    The index of the first picture item you want to replace.
  10794. oldCount    The total number of picture items you want to replace. A value of 0 indicates that you want to insert new picture items before the existing picture item indicated by the index parameter, rather than replace items. You may supply the selectToEnd constant (–1) to indicate that you want to replace all picture items (starting with the picture item indicated by the index parameter.)
  10795. newCount    The total number of new picture items to insert into the picture. A value of 0 specifies that you do not want to insert new items into the picture; instead, the existing items you specified with the index and oldCount parameters are removed.
  10796. shapes    An array of references to the shapes to include as the new picture items in the new picture geometry.
  10797. styles    An array of references to the style objects you want to use as overriding styles in the new picture geometry. You may provide nil for this parameter if you do not want any overriding styles.
  10798. inks    An array of references to the ink objects you want to use as overriding inks in the new picture geometry. You may provide nil for this parameter if you do not want any overriding inks.
  10799. transforms    An array of references to the transform objects you want to use as overriding transforms in the new picture geometry. You may provide nil for this parameter if you do not want any overriding transforms.
  10800. DESCRIPTION
  10801. The GXSetPictureParts function allows you to insert new picture items into a picture, to remove picture items from a picture, or to replace picture items with new picture items. In any of these three cases, the target parameter specifies the picture to be modified, the oldCount parameter specifies the number of items to remove, the newCount parameter specifies the number of items to add, and the shapes, styles, inks, and transforms parameters specify the information for the new picture items.
  10802. n    To insert picture items, set the oldCount parameter to 0. Use the index parameters to specify where to add the new picture items. (This function inserts the new picture items before the existing item you specify with the index parameter. For example, if you specify 1 for this parameter, the new picture items are inserted before the first item of the existing picture item list.)
  10803. n    To remove picture items, set the newCount parameter ot 0 and the shapes, styles, inks, and transforms parameters to nil. Use the index and oldCount parameters to specify which picture items to remove. 
  10804. n    To replace picture items, use the index and oldCount parameters to specify the existing picture items to remove and use the newCount, shapes, styles, inks, and transforms parameters to specify the new picture items to insert in their place.
  10805. To maintain correct owner counts, this function disposes of the shapes, styles, inks, and transforms referenced by any items removed from the original picture geometry.
  10806. RESULT CODESErrors    
  10807. out_of_memory    
  10808. shape_is_nil    
  10809. parameter_out_of_range    
  10810. inconsistent_parameters    
  10811. index_is_less_than_nil    
  10812. count_is_less_than_zero    
  10813. cannot_set_item_shapes_to_nil    
  10814. cannot_use_original_item_shapes_when_growing_picture    
  10815. Warnings    
  10816. picture_expected    
  10817. index_out_of_range    
  10818. count_out_of_range    
  10819. shape_access_not_allowed    
  10820. picture_cannot_contain_itself    
  10821. cannot_dispose_default_style    
  10822. cannot_dispose_default_ink    
  10823. cannot_dispose_default_transform    
  10824. cannot_dispose_default_colorProfile    
  10825.  
  10826. SEE ALSO
  10827. For information about picture items and their overriding styles, inks, and transforms, see “About Picture Shapes” beginning on page 6-3.
  10828. For examples of this function, see “Removing and Replacing Items in a Picture” beginning on page 6-31.
  10829. To extract information from a subset of the items contained in a picture shape’s geometry, use the GXGetPictureParts function, which is described on page 6-55.
  10830. To replace every item in a picture geometry, use the GXSetPicture function, which is described on page 6-53.
  10831. For information about disposing of shapes, see the “Shape Objects” chapter of Inside Macintosh: QuickDraw GX Objects.
  10832. Drawing Pictures
  10833.  
  10834. QuickDraw GX provides two methods of drawing a picture:
  10835. n    You can create a picture shape (by calling the GXNewPicture function, by copying an existing picture shape, and so on) and use the GXDrawShape function to draw the picture.
  10836. n    You can create an array of shape references, and arrays of references to overriding styles, inks, and transforms, and use the GXDrawPicture function to draw the corresponding picture.
  10837. In general, you should use the GXDrawShape function to draw any QuickDraw GX graphic, including picture shapes. In fact, the GXDrawPicture function creates a temporary picture shape, uses the GXDrawShape function to draw it, and then disposes of it. The GXDrawShape function is described in the “Shape Objects” chapter of Inside Macintosh: QuickDraw GX Objects.
  10838. You would typically use the GXDrawPicture function only in simple situations—for example, if you knew you wanted to draw a particular picture only once. 
  10839. GXDrawPicture  
  10840.  
  10841. You can use the GXDrawPicture function to draw a picture without encapsulating the items of the picture geometry in a picture shape.
  10842. void gxDrawPicture(long count, const gxShape shapes[], 
  10843.                          const gxStyle styles[], const gxInk inks[],
  10844.                          const gxTransform transforms[]);
  10845. count    The number of picture items in the new picture shape.
  10846. shapes    An array of references to the shapes you want to draw.
  10847. styles    An array of references to the style objects you want to use to override the styles of the shapes specified in the shapes parameter. You may provide nil for this parameter if you do not want any overriding styles.
  10848. inks    An array of references to the ink objects you want to use to override the inks of the shapes specified in the shapes parameter. You may provide nil for this parameter if you do not want any overriding inks.
  10849. transforms    An array of references to the transform objects you want to use to override the transforms of the shapes specified in the shapes parameter. You may provide nil for this parameter if you do not want any overriding transforms.
  10850. DESCRIPTION
  10851. The GXDrawPicture function allows you to draw a picture without having to create a picture shape yourself. Instead, you specify the items of a picture geometry using the shapes, styles, inks, and transforms parameters.
  10852. The GXDrawPicture function creates a temporary picture shape using the values specified in these arrays, and draws the picture shape using the GXDrawShape function, which is described in detail in Inside Macintosh: QuickDraw GX Objects.
  10853. The GXDrawPicture function calls the GXNewPicture function to create the temporary picture shape. See the description of the GXNewPicture function on page 6-50 for information about how QuickDraw GX creates picture shapes.
  10854. RESULT CODESErrors    
  10855. out_of_memory    
  10856. parameter_is_nil    
  10857. shape_is_nil    
  10858. parameter_out_of_range    
  10859.  
  10860. SEE ALSO
  10861. For information about picture items and their overriding styles, inks, and transforms, see “About Picture Shapes” beginning on page 6-3.
  10862. For an example of this function, see “Creating and Drawing Picture Shapes” beginning on page 6-22.
  10863. To encapsulate a picture geometry in a picture shape, use the GXNewPicture function, described on page 6-50.
  10864. To draw a picture shape, use the DrawShape function, described in the “Shape Objects” chapter of Inside Macintosh: QuickDraw GX Objects.
  10865. Hit-Testing Pictures
  10866.  
  10867. This section describes the GXHitTestPicture function. To hit-test a picture, this function
  10868. n    hit-tests each shape contained in the picture
  10869. n    compiles a list of shapes that were hit
  10870. n    selects one of the shapes using criteria you provide
  10871. n    provides information about the shape in the picture that was hit
  10872. For more information about how QuickDraw GX hit-tests shapes, see the chapter “Shape Objects” and the chapter “Transform Objects” of Inside Macintosh: QuickDraw GX Objects.
  10873. GXHitTestPicture  
  10874.  
  10875. You can use the GXHitTestPicture function to determine whether a test point hits a picture shape and to discover which shape in the picture hierarchy is hit.
  10876. gxShape GXHitTestPicture(gxShape target, const gxPoint *test,
  10877.                                  gxHitTestInfo *result, long level, 
  10878.                                  long depth);
  10879. target    A reference to the picture shape to hit-test.
  10880. test    A pointer to a point structure. The GXHitTestPicture function determines whether the location specified by this point hits the target picture.
  10881. result    A pointer to a hit-test information structure. On output, this structure contains information identifying the part of the target picture that was hit by the test point.
  10882. level    A level in the picture hierarchy. This parameter, along with the depth parameter, is used to determine which shape in the picture to return as the function result.
  10883. depth    A shape depth in the picture as drawn. This parameter, along with the level parameter, is used to determine which shape in the picture to return as the function result.
  10884. function result    A reference to the shape (at the specified shape depth and hierarchy level) hit by the test point.
  10885. DESCRIPTION
  10886. The GXHitTestPicture function compares the point indicated by the test parameter with each shape in the picture referenced by the target parameter. To determine whether the test point hits a shape, this function uses the hit-test parameters contained in that shape’s transform object, or contained in the overriding transform if there is one.
  10887. If the target picture contains shapes that overlap when drawn, more than one shape might be hit by the test point. The function uses the depth parameter to select which of these shapes is the hit shape. If you set this parameter to 1, the function selects the frontmost shape as the hit shape. If you set this parameter to 2, the function selects the shape immediately behind the frontmost shape as the hit shape, and so on.
  10888. Before returning a reference to the hit shape, this function examines how deep into the target picture’s hierarcy the hit shape is. If the hit shape is deeper into the hierarchy than the level indicated by the level parameter, this function does not return a reference to the hit shape. Instead, it returns a reference to the subpicture at the appropriate level of the target picture’s hierarcy that contains the hit shape.
  10889. For example, if the hit shape is at level 2 of the picture hierarchy—that is, it is an item of a picture which is an item of the target picture—then specifying a value of 2 for the level parameter causes the function to return a reference to the shape as the function result. However, if you specify a value of 1 for the level parameter, the function returns a reference to the picture that contains the hit shape, rather than a reference to the hit shape itself.
  10890. This function also returns information in the structure pointed to by the result parameter:
  10891. n    The what field indicates the shape part hit by the test point.
  10892. n    The index field indicates the index of the geometric point hit by the test point.
  10893. n    The distance field indicates the distance of the test point from the shape part hit.
  10894. n    The which field contains a reference to the hit shape.
  10895. n    The containerPicture fieldcontains a reference to the picture that contains the hit shape.
  10896. n    The containerIndex field indicates the index of the hit shape within the container picture.
  10897. n    The totalIndex field indicates the overall index of the hit shape within the target picture.
  10898. For more information about the gxHitTestInfo structure, see the chapter “Transform Objects” in Inside Macintosh: QuickDraw GX Objects. (*** Make sure that this cross reference is correct. ***)
  10899. RESULT CODESErrors    
  10900. out_of_memory    
  10901. parameter_is_nil    
  10902. parameter_out_of_range    
  10903. Warnings    
  10904. picture_expected    
  10905. unable_to_traverse_open_contour_that_starts_or_ends_off_the_curve    
  10906. character_substitution_took_place    
  10907. font_substitution_took_place    
  10908.  
  10909. SEE ALSO
  10910. For more information about hit-testing shapes, see the “Shape Objects” and “Transform Objects” chapters of Inside Macintosh: QuickDraw GX Objects.
  10911. For examples of this function, see “Hit-Testing Picture Shapes” beginning on page 6-20.
  10912.  
  10913.  
  10914. Summary of Picture Shapes
  10915.  
  10916. Data Types
  10917.  
  10918. Pictures
  10919. typedef struct {
  10920.     char                     *image;                    /* pointer to the pixel image */
  10921.     long                     width;                    /* picture width */
  10922.     long                     height;                    /* picture height */
  10923.     long                     rowBytes;                    /* number of bytes per row */
  10924.     long                     pixelSize;                    /* number of bits per pixel */
  10925.     gxColorSpace                     space;                    /* color space */
  10926.     gxColorSet                     set;                    /* color set */
  10927.     gxColorProfile                 profile;                        /* color profile */
  10928. } gxPicture;
  10929. Functions
  10930.  
  10931. Creating Picture Shapes
  10932. gxShape GXNewPicture    (long count, const gxShape shapes[], 
  10933. const gxStyle styles[], const gxInk inks[],
  10934. const gxTransform transforms[])
  10935. Getting and Setting Picture Geometries
  10936. long GXGetPicture    (gxShape source, gxShape shapes[], 
  10937. gxStyle styles[], gxInk inks[], 
  10938. gxTransform transforms[]);
  10939. void GXSetPicture    (gxShape target, long count, 
  10940. const gxShape shapes[], const gxStyle styles[],
  10941. const gxInk inks[], 
  10942. const gxTransform transforms[]);
  10943. Editing Picture Parts
  10944. long GXGetPictureParts    (gxShape source, long index, long count,
  10945. gxShape shapes[], gxStyle styles[], 
  10946. gxInk inks[], gxTransform transforms[])
  10947. void GXSetPictureParts    (gxShape target, long index, long oldCount,
  10948. long newCount, const gxShape shapes[],
  10949. const gxStyle styles[], 
  10950. const gxInk inks[], 
  10951. const gxTransform transforms[]);
  10952. Drawing Pictures
  10953. void gxDrawPicture    (long count, const gxShape shapes[], 
  10954. const gxStyle styles[], const gxInk inks[],
  10955. const gxTransform transforms[]);
  10956. Hit-Testing Pictures
  10957. gxShape GXHitTestPicture    (gxShape target, const gxPoint *test,
  10958. gxHitTestInfo *result, long level, 
  10959. long depth);
  10960. Glossary
  10961.  
  10962.  
  10963. bitmap(1) A QuickDraw GX data structure that describes a pixel map on a physical device. A bitmap structure is a property of a view device object. (2) A type of QuickDraw GX shape.
  10964. bitmap color profileThe object that specifies color-matching information about the device on which a bitmap was created.
  10965. bitmap color setAn array of color values associated with a bitmap. If a bitmap uses a color set (as opposed to a color space), each pixel value in the bitmap’s pixel image represents an index into this color set.
  10966. bitmap color spaceA color space associated with a bitmap. If a bitmap uses a color space (as opposed to a color set), each pixel value in the bitmap’s pixel image represents a color value in this color space.
  10967. bitmap heightThe number of pixels in each column of a bitmap.
  10968. bitmap positionThe position of the upper-left corner of a bitmap in geometry space—that is, before transformations are applied.
  10969. bitmap widthThe number of pixels in each row of a bitmap.
  10970. bytes per rowThe number of bytes in a pixel image required to represent each row of a bitmap.
  10971. capSee cap property. 
  10972. cap propertyA property of the style object used to specify how the end points of contours should be drawn.
  10973. cap shapeA shape drawn at the end points of another shape.
  10974. color rampA shape that blemds from one color to another.
  10975. contourA connected series of lines and curves. The geometry property of a goemetric shape is made up of one or more contours.
  10976. contour directionA value, either clockwise or counterclockwise, that QuickDraw GX assigns to each contour in a shape’s geometry.
  10977. contour indexA number used to specify a particular geometric point in a contour: the first geometric point in a contour has contour index 1, and so on. See also geometric index. 
  10978. control pointA geometric point used to control the curvature of a curve.
  10979. curve errorA property of the style object used to specify the accuracy of certain operations, such as converting paths to polygons.
  10980. curve shapeA type of QuickDraw GX shape that encapsulates a Bézier curve.
  10981. dashSee dash property. 
  10982. dash advanceThe distance between dashes in a dashed contour.
  10983. dash phaseHow far into a dash a contour begins.
  10984. dash propertyA property of the style object used to draw contours as repeated patterns of shapes rather than continous lines.
  10985. dash shapeA shape used to dash the contours of another shape.
  10986. depthA number indicating the position in front to back order at which a picture item is drawn. The greater a shape’s depth, the more other shapes drawn on top of the shape.
  10987. ditherTo approximate colors that a display device cannot draw with patterns of similar colors that the display device can draw.
  10988. empty shapeA type of QuickDraw GX shape. Empty shapes have no geometry, are contained by every other shape, and do not appear when drawn.
  10989. even-odd ruleA rule used when drawing filled shapes to determine which areas are filled. The even-odd rule does not fill areas which lie under overlapping contours. See also winding-number rule. 
  10990. fillSee shape fill. 
  10991. filled shapeA shape that describes an area—the area surrounded by the contours of the shape’s geometry. The shape fill of a filled shape can be even-odd shape fill, winding-number shape fill, or one of the inverse shape fills.
  10992. framed shapeA shape that describes an outline—the outline defined by the contours of the shape’s geometry. The shape fill of a framed shape can be open-frame fill or closed-frame fill.
  10993. full shapeA type of QuickDraw GX shape. Full shapes have no geometry, contain every other shape, and cover all area when drawn.
  10994. geometric indexA number used to specify a particular geometric point in a geometry: the first geometric point in a geometry has geometric index 1, and so on. Whereas contour indexes start over with each contour in a geometry, geometric indexes do not.
  10995. geometric penThe pen used by QuickDraw GX to draw framed shapes. This pen has pen width, pen placement, and can be capped, joined, dashed, and patterned.
  10996. geometric pointAn x-coordinate/y-coordinate pair used to specify a location in a shape’s geometry. Geometric points can specify the ends of lines or curves or the off-curve control points used to control curvature.
  10997. geometryA property of a QuickDraw GX shape object. A shape’s geometry is the specification of the actual size, position, and form of the shape. For example, for a rectangle shape, the geometry specifies the locations (in local coordinates) of the rectangle’s corners.
  10998. grid point(1) The specification of a location on the QuickDraw GX coordinate system. Grid points are infinitely thin, and fall between pixels. (2) The distance between two grid points, or 1/72 inch.
  10999. indexSee contour index and geometric index. 
  11000. joinSee join property. 
  11001. join propertyA property of the style object used to specify how the corners of a geometric shape should be drawn.
  11002. join shapeA shape drawn at the corners of another shape.
  11003. levelA number indicated how many pictures separate a shape from the root picture in a picture hierarchy.
  11004. level capA cap shape that is not rotated to match the angle of contour on which it is drawn.
  11005. level joinA join shape that is not rotated to match the angle that bisects the corner on which it is drawn.
  11006. miterThe length a sharp join can reach before being truncated.
  11007. off-curve control pointSee control point. 
  11008. off-path control pointSee control point. 
  11009. offscreen bitmapA bitmap that exists in memory or on disk but is not associated with a physical display device.
  11010. overriding inkAn optional part of a picture item. If a picture item has an overriding ink, QuickDraw GX uses the information in the overriding ink when drawing the item, rather than the information in the original ink.
  11011. overriding styleAn optional part of a picture item. If a picture item has an overriding style, QuickDraw GX uses the information in the overriding style when drawing the item, rather than the information in the original style.
  11012. overriding transformAn optional part of a picture item. If a picture item has an overriding transform, QuickDraw GX uses the information in the overriding transform when drawing the item, rather than the information in the original transform.
  11013. path contourA connected series of straight lines and curves.
  11014. path shapeA type of QuickDraw GX shape. The geometry of a path shape is made up of 0, 1, or more path contours.
  11015. patternSee pattern property. 
  11016. pattern gridA pair of vectors that determine the placement of a pattern shape over the area of another shape.
  11017. pattern propertyA property of the style object used to specify how the area of a shape should be filled.
  11018. pattern shapeA shape drawn repeatedly over the area of another shape.
  11019. picture hierarchyA picture shape that contains other picture shapes as items.
  11020. picture itemAn element of a picture shape’s geometry. Each picture item contains a reference to a shape and, optionally, a reference to an overriding style, an overriding ink, and an overriding transform.
  11021. picture shapeA type of QuickDraw GX shape that represents a collection of other shapes.
  11022. pixel depthSee pixel size. 
  11023. pixel imageA two-dimensional array of pixel values, each of which describes the color of one pixel in a bitmap.
  11024. pixel sizeThe number of bits required to represent the color information for each pixel in a bitmap. Also called pixel depth.
  11025. pixel valueA series of bits in a bitmap’s pixel image that represent a single pixel of the bitmap. This value can represent a color value (if the bitmap uses a color space) or an index into a color set (if the bitmap uses a color set).
  11026. pointSee control point, geometric point, grid point, and point shape. 
  11027. point shapeA type of QuickDraw GX shape. The geometry of a point shape specifies an x coordinate and a y coordinate. Point shapes appear as a single pixel (if the pen width is 0) or as a cap shape (if the pen width is greater than 0).
  11028. polygon contourA connected series of straight lines.
  11029. polygon shapeA type of QuickDraw GX shape. The geometry of a polygon shape is made up of 0, 1, or more polygon contours.
  11030. primitive geometryA geometry with stylistic information incorporated into it.
  11031. reduceTo remove unnecessary geometric points from a geometry.
  11032. shape(1) A graphic or typographic item (such as a geometric shape, a bitmap, or a line of text) created and drawn with QuickDraw GX. (2) A set of QuickDraw GX objects that, taken together, describe the type and characteristics of such a graphic or typographic item. A shape consists of a shape object, a style object, an ink object, and a transform object. 
  11033. shape fillA property of a shape object. The shape fill specifies whether and how QuickDraw GX fills in the outlines of a shape that it draws.
  11034. shape typeA property of a shape object. The shape type specifies the classification (such as point, line, bitmap, or text) of a particular shape.
  11035. simplifyTo remove crossed and overlapping contours from a geometry.
  11036. styleSee style object. 
  11037. style attributeOne of a set of flags that affect how the information in a style object affects a shape.
  11038. style objectA QuickDraw GX object associated with a shape object. A style object contains information that affects the visual appearance of a shape when it is drawn.
  11039. transform concatenationThe process by which QuickDraw GX combines the clips and mappings of transform objects at different levels of a picture hierarchy when drawing a picture shape.
  11040. typeSee shape type. 
  11041. type conversionThe process of change a shape from one shape type to another. Often the geometry of the shape is significantly affected during this process.
  11042. unique items attributeA shape attribute that affects the way items are added to picture shapes.
  11043. winding-number ruleA rule used when drawing filled shapes to determine which areas are filled. The winding-number rule does fill areas which lie under overlapping contours. See also even-odd rule. 
  11044. Index
  11045.  
  11046.  
  11047. Symbols
  11048.  
  11049. 2-86 to 2-87, 5-10 to 5-12
  11050. A
  11051.  
  11052. area of a shape4-40, 4-74
  11053. arithmetic operations on geometric shapes4-19 to 4-20, 4-53 to 4-59, 4-87 to 4-97
  11054. attributes3-96
  11055. auto-advance dash attribute3-67 to 3-69, 3-99
  11056. auto-inset style attribute3-19 to 3-20, 3-93
  11057. B
  11058.  
  11059. bend dash attribute3-71 to 3-75, 3-98
  11060. Bézier curves2-17 to 2-19
  11061. bitmap color profile5-5
  11062. bitmap color sets5-5
  11063. bitmap color space5-5
  11064. bitmap geometries
  11065. editing5-49 to 5-50, 5-67 to 5-72
  11066. properties of5-3 to 5-7
  11067. replacing5-64 to 5-67
  11068. structure of5-58 to 5-60
  11069. bitmap height5-5 to 5-7, 5-13 to 5-26
  11070. bitmap shapes
  11071. and view devices5-42 to 5-47
  11072. applying geometric operations on5-54
  11073. applying ink-related functions to5-55
  11074. applying shape-related functions to5-53 to 5-54
  11075. applying style-related functions to5-55
  11076. applying transfer modes to5-8, 5-30 to ??
  11077. applying transform-related functions to5-55 to ??
  11078. applying view-related functions to5-57
  11079. black-and-white?? to 5-19
  11080. clipping5-39 to 5-40
  11081. color5-6 to 5-19
  11082. converting other shapes to5-32 to 5-35
  11083. creating and drawing5-13 to ??, 5-62, 5-73, 5-74
  11084. dithering5-28 to 5-29
  11085. drawing with halftones5-28 to 5-29
  11086. functions for5-61 to 5-74
  11087. introduced1-15 to 1-17
  11088. mapping5-9, 5-35 to 5-39
  11089. and map transform shape attribute5-37
  11090. offscreen5-12, 5-42 to 5-49
  11091. rotating5-37
  11092. scaling5-38 to 5-39
  11093. skewing5-36
  11094. and view devices5-10, 5-12
  11095. bitmap width5-5 to 5-7, 5-13 to 5-26
  11096. black-and-white bitmaps?? to 5-19
  11097. bounding rectangle of a shape4-39, 4-42 to 4-45, 4-76, 4-77
  11098. break dash attribute3-71 to 3-75, 3-99
  11099. breaking contours4-25 to 4-27
  11100. bytes per row in bitmap geometries5-5 to 5-7
  11101. unaligned5-18
  11102. C
  11103.  
  11104. cap attributes3-94 to 3-95
  11105. cap record structure3-94
  11106. caps3-23 to 3-25
  11107. adding to a shape3-53 to 3-56
  11108. definition of cap record structure3-94
  11109. functions for3-116 to 3-121
  11110. interactions with joins, dashes, patterns3-33 to 3-35, 3-86 to 3-90
  11111. level3-24, 3-95
  11112. standard3-24, 3-56 to 3-58
  11113. caps.See also cap style property
  11114. cap style property3-24
  11115. functions for3-116 to 3-121
  11116. cap style property.See also caps
  11117. center frame style attribute3-18 to 3-19, 3-93
  11118. center of a shape4-73
  11119. clip dash attribute3-29, 3-99
  11120. clip-dash attribute3-65
  11121. clipping
  11122. dashes3-65
  11123. clipping dashes3-99
  11124. clockwise contour direction4-6
  11125. closed-frame fill
  11126. and multiple contours2-56
  11127. closed-frame shape fill
  11128. compared to even-odd shape fill2-19, 2-21
  11129. compared to open-frame shape fill2-21
  11130. and crossed contours2-45
  11131. and multiple contours2-54
  11132. and overlapping contours2-47
  11133. colinear geometric points4-27
  11134. color bitmaps5-6 to 5-19
  11135. color profiles
  11136. of bitmap shapes5-5
  11137. color ramps5-23
  11138. color spaces
  11139. of bitmap shapes5-5
  11140. concatenating transforms6-15 to 6-19, 6-39 to 6-40
  11141. containment, testing shapes for4-16 to 4-18, 4-51 to 4-53, 4-83 to 4-87
  11142. contour direction4-4 to 4-8
  11143. determining4-61
  11144. effect on shape fill4-21 to 4-25
  11145. reversing4-21 to 4-25, 4-63
  11146. contour index2-21
  11147. contours4-4 to 4-8
  11148. breaking4-25 to 4-27, 4-64
  11149. counting4-27
  11150. determining direction4-61
  11151. finding a specific point on4-38, 4-72
  11152. left side4-4
  11153. removing crossed4-67
  11154. removing overlapping4-67
  11155. removing unnecessary contour breaks4-67
  11156. right side4-4
  11157. true inside4-8
  11158. control bits of path geometries2-23, 2-49
  11159. control points2-17, 2-23, 2-49
  11160. coordinate spaces3-21 to 3-22
  11161. counterclockwise contour direction4-6
  11162. crossed contours
  11163. removing4-29, 4-67
  11164. curve error style property3-14 to 3-15, ?? to 3-46
  11165. effect when converting shapes3-43 to ??
  11166. effect when reducing3-46 to 3-48
  11167. functions for3-107 to 3-112
  11168. curve geometries
  11169. definition of2-17
  11170. editing2-68 to 2-70, 2-107
  11171. structure of2-91
  11172. curve join attribute3-96
  11173. curve joins3-96
  11174. curve shapes2-17 to 2-19
  11175. converting other shapes to2-61 to 2-65
  11176. creating and drawing2-39 to 2-40
  11177. default2-19
  11178. definition of2-17
  11179. dividing in two2-18
  11180. D
  11181.  
  11182. dash advance3-29, 3-63 to 3-66, 3-98
  11183. dash attributes3-63 to 3-66, 3-98 to 3-99
  11184. as field of dash record3-97
  11185. auto-advance dash attribute3-67 to 3-69, 3-99
  11186. bend dash attribute3-71 to 3-75, 3-98
  11187. break dash attribute3-71 to 3-75, 3-99
  11188. clip dash attribute3-99
  11189. level dash attribute3-99
  11190. dashes3-27 to 3-31
  11191. adding to a shape3-63 to 3-66
  11192. adjusting to fit contours3-67 to 3-69
  11193. auto-advancing3-67 to 3-69, 3-99
  11194. bending3-30, 3-71 to 3-75, 3-98
  11195. breaking3-29, 3-71 to 3-75, 3-99
  11196. clipping3-65, 3-99
  11197. definition of dash record structure3-97 to 3-98
  11198. determining dash positions3-131
  11199. effect of shape fill3-97
  11200. functions for3-126 to 3-132
  11201. hairline3-74
  11202. insetting3-69 to 3-70
  11203. interactions with caps, joins, patterns3-33 to 3-35, 3-86 to 3-90
  11204. level3-99
  11205. phasing3-66, 3-98
  11206. positions, determining3-77 to 3-80
  11207. scaling3-65, 3-98
  11208. text used as3-75 to 3-76
  11209. dash phase3-29, 3-63 to 3-66, 3-98
  11210. dash positions
  11211. determining3-131
  11212. dash record structures3-97 to 3-98
  11213. dash style property3-27
  11214. functions for3-126 to 3-132
  11215. default shapes
  11216. curve2-19
  11217. line2-16
  11218. path2-24
  11219. point2-15
  11220. polygon2-23
  11221. rectangle2-20
  11222. depth of picture items6-45
  11223. device grid style attribute3-21, 3-41 to 3-43, 3-93
  11224. difference operation4-19, 4-57, 4-92
  11225. dithering
  11226. bitmaps5-28 to 5-29
  11227. duplicate geometric points4-27
  11228. E
  11229.  
  11230. Each3-95
  11231. empty shapes
  11232. creating and drawing2-26
  11233. definition of2-15
  11234. end caps3-53 to 3-56, 3-94
  11235. even-odd rule for filling shapes2-12
  11236. even-odd shape fill
  11237. compared to closed-frame shape fill2-19, 2-21
  11238. compared to open-frame shape fill2-21
  11239. compared to winding fill2-12
  11240. compared to winding shape fill2-22
  11241. and concentric clockwise contours2-55
  11242. and crossed contour2-46
  11243. defined2-12
  11244. and overlapping contour2-47
  11245. exclusion operation4-19, 4-58, 4-95
  11246. F
  11247.  
  11248. framed shape fills2-10
  11249. .See also closed-frame shape fill; open-frame shape fill2-5
  11250. full shapes
  11251. creating and drawing2-26
  11252. definition of2-15
  11253. G
  11254.  
  11255. geometric shapes
  11256. and shape-related functions to2-87
  11257. geometric arithmetic4-19 to 4-20, 4-53 to 4-59, 4-87 to 4-97
  11258. difference4-57, 4-92
  11259. exclusion4-58, 4-95
  11260. intersection4-55, 4-87, 4-89
  11261. inversion4-59, 4-96
  11262. reverse difference4-57, 4-94
  11263. union4-56, 4-88, 4-91
  11264. geometric index2-21
  11265. geometric information
  11266. determining4-36 to 4-42, 4-71 to 4-77
  11267. shape area4-40, 4-74
  11268. shape bounds4-39, 4-42 to 4-45, 4-76, 4-77
  11269. shape center4-73
  11270. shape length4-38, 4-71
  11271. shape length to point4-38, 4-72
  11272. geometric pen3-15 to 3-16
  11273. geometric points
  11274. colinear4-27
  11275. duplicate4-27
  11276. effect of fractional coordinate values2-35 to 2-36
  11277. removing unnecessary4-27
  11278. replacing2-68 to 2-70
  11279. geometric properties of style objects3-91 to 3-92
  11280. geometric shapes2-5 to 2-141
  11281. adding caps to3-53 to 3-56, 3-116 to 3-121
  11282. adding dashes to3-126 to 3-132
  11283. adding joins to3-58 to 3-61, 3-121 to 3-126
  11284. adding patterns to3-81 to 3-83, 3-132 to 3-139
  11285. adding standard caps to3-56 to 3-58
  11286. adding standard joins to3-61 to 3-63
  11287. converting between types2-57 to 2-68, 2-87 to 2-88
  11288. creating2-26 to 2-57, 2-94 to 2-102
  11289. dashing3-63 to 3-66
  11290. dashing with text3-75 to 3-76
  11291. data structures for2-90 to 2-94
  11292. editing2-68 to 2-85, 2-102 to 2-133
  11293. functions for2-94 to 2-138
  11294. introduced1-6 to 1-11
  11295. and shape-related functions to2-86
  11296. stylistic variations. See style properties of geometric shapes
  11297. geometric shapes.See also curve shapes; empty shapes; full shapes; line shapes; path shapes; point shapes; polygon shapes; rectangle shapes
  11298. geometries
  11299. constraining to device grids3-41 to 3-43
  11300. constraining to grids3-39 to 3-41
  11301. editing2-81 to 2-85, 2-115 to 2-133
  11302. incorporating style information into4-34 to 4-36, 4-70
  11303. of point shapes2-8
  11304. removing unnecessary geometric points4-66
  11305. removing unnecessary points4-27
  11306. replacing2-102 to 2-114
  11307. graphics pen
  11308. insetting3-50 to 3-51
  11309. outsetting3-51 to 3-53
  11310. grids3-21 to 3-22
  11311. constraining geometries to3-39 to 3-41
  11312. for patterns3-100
  11313. gxBitmapDataSourceAlias structure5-61
  11314. gxBitmap structure5-58
  11315. GXBreakShape function4-25 to 4-27, 4-64
  11316. gxCapAttributes enumeration3-95
  11317. gxCapRecord structure3-94
  11318. GXContainsBoundsShape function4-51 to 4-53, 4-85
  11319. GXContainsRectangle function4-51 to 4-53, 4-84
  11320. GXContainsShape function4-51 to 4-53, 4-86
  11321. GXCountShapeContours function2-116, 4-25 to 4-27
  11322. GXCountShapePoints function2-116
  11323. gxCurve structure2-91
  11324. gxDashAttributes enumeration3-98
  11325. gxDashRecord structure3-97
  11326. GXDifferenceShape function4-57, 4-92
  11327. GXDrawBitmap function5-73, 5-74
  11328. GXDrawCurve function2-39 to 2-40, 2-135
  11329. GXDrawLine function2-32 to 2-33, 2-135
  11330. GXDrawPaths function2-50 to 2-51, 2-138
  11331. GXDrawPicture function6-22 to 6-25, 6-60
  11332. GXDrawPoint function2-27 to 2-28, 2-134
  11333. GXDrawPolygons function2-137
  11334. GXDrawRectangle function2-36, 2-136
  11335. GXExcludeShape function4-58, 4-95
  11336. GXGetBitmap function5-64
  11337. GXGetBitmapParts function5-49 to 5-50, 5-70
  11338. GXGetCurve function2-106
  11339. GXGetLine function2-104
  11340. GXGetPathParts function2-79 to 2-81, 2-126
  11341. GXGetPaths function2-112
  11342. GXGetPicture function6-26 to 6-28, 6-52
  11343. GXGetPictureParts function6-28 to 6-33, 6-55
  11344. GXGetPoint function2-102
  11345. GXGetPolygonParts function2-71 to 2-78, 2-122
  11346. GXGetPolygons function2-110
  11347. GXGetRectangle function2-108
  11348. GXGetShapeArea function4-40, 4-74
  11349. GXGetShapeBounds function4-39, 4-76
  11350. GXGetShapeCap function3-53 to 3-56, 3-56 to 3-58, 3-119
  11351. GXGetShapeCenter function4-73
  11352. GXGetShapeCurveError function3-110
  11353. GXGetShapeDash function3-63 to 3-66, 3-129
  11354. GXGetShapeDashPositions function3-77 to 3-80, 3-131
  11355. GXGetShapeDirection function4-21 to 4-25, 4-61
  11356. GXGetShapeIndex function2-117
  11357. GXGetShapeJoin function3-58 to 3-61, 3-61 to 3-63, 3-124
  11358. GXGetShapeLength function4-38, 4-71
  11359. GXGetShapeLengthToPoint function4-38
  11360. GXGetShapeParts function2-81 to 2-85, 2-129
  11361. GXGetShapePattern function3-81 to 3-83, 3-135
  11362. GXGetShapePatternPositions function3-83 to 3-85, 3-138
  11363. GXGetShapePen function3-114
  11364. GXGetShapePixel function5-68
  11365. GXGetShapePoints function2-119
  11366. GXGetStyleCap function3-117
  11367. GXGetStyleCurveError function3-108
  11368. GXGetStyleDash function3-126
  11369. GXGetStyleJoin function3-122
  11370. GXGetStylePattern function3-133
  11371. GXGetStylePen function3-112
  11372. GXHitTestPicture function6-40 to 6-45, 6-61
  11373. GXInsetShape function4-45 to 4-47, 4-79
  11374. GXIntersectRectangle function4-87
  11375. GXIntersectShape function4-55, 4-89
  11376. GXInvertShape function4-59, 4-96
  11377. gxJoinAttributes enumeration3-96
  11378. gxJoinRecord structure3-95
  11379. gxLevelEndCap3-95
  11380. gxLine structure2-91
  11381. gxLongRectangle structure5-60
  11382. GXNewBitmap function5-13 to 5-26, 5-62
  11383. GXNewCurve function2-39 to 2-40, 2-97
  11384. GXNewLine function2-33 to 2-34, 2-96
  11385. GXNewPaths function2-51, 2-101
  11386. GXNewPicture function6-22 to 6-26, 6-50
  11387. GXNewPoint function2-28 to 2-29, 2-95
  11388. GXNewPolygons function2-99
  11389. GXNewRectangle function2-36 to 2-38, ?? to 2-40, 2-98
  11390. gxPaths structure2-93 to 2-94
  11391. gxPatternAttributes enumeration3-100
  11392. gxPatternRecord structure3-99
  11393. gxPoint structure2-90
  11394. gxPolygons structure2-92 to 2-93
  11395. gxPolygon structure2-92
  11396. GXPrimitiveShape function4-34 to 4-36, 4-69
  11397. gxRectangle structure2-91 to 2-92
  11398. GXReduceShape function4-27 to 4-29, 4-66
  11399. GXReverseDifferenceShape function4-57, 4-94
  11400. GXReverseShape function4-21 to 4-25, 4-63
  11401. GXSetBitmap function5-65
  11402. GXSetBitmapParts function5-49 to 5-50, 5-71
  11403. GXSetCurve function2-68 to 2-70, 2-107
  11404. GXSetLine function2-34 to 2-36, 2-68 to 2-70, 2-105
  11405. GXSetPathParts function2-79 to 2-81, 2-127
  11406. GXSetPaths function2-114
  11407. GXSetPathst function2-68 to 2-70
  11408. GXSetPicture function6-26 to 6-28, 6-53
  11409. GXSetPictureParts function6-28 to 6-33, 6-57
  11410. GXSetPoint function2-28 to 2-31, 2-68 to 2-70, 2-103
  11411. GXSetPolygonParts function2-71 to 2-78, 2-123
  11412. GXSetPolygons function2-68 to 2-70, 2-111
  11413. GXSetRectangle function2-68 to 2-70, 2-109
  11414. GXSetShapeBounds function4-42 to 4-45, 4-77
  11415. GXSetShapeCap function3-53 to 3-56, 3-56 to 3-58, 3-120
  11416. GXSetShapeCurveError function3-111
  11417. GXSetShapeDash function3-63 to 3-66, 3-130
  11418. GXSetShapeJoin function3-58 to 3-61, 3-61 to 3-63, 3-125
  11419. GXSetShapeParts function2-81 to 2-85, 2-131
  11420. GXSetShapePattern function3-81 to 3-83, 3-137
  11421. GXSetShapePen function3-115
  11422. GXSetShapePixel function5-24 to 5-26, 5-69
  11423. GXSetShapePoints function2-121
  11424. GXSetStyleCap function3-118
  11425. GXSetStyleCurveError function3-109
  11426. GXSetStyleDash function3-128
  11427. GXSetStyleJoin function3-123
  11428. GXSetStylePattern function3-134
  11429. GXSetStylePen function3-113
  11430. GXShapeLengthToPoint function4-72
  11431. GXSimplifyShape function4-29 to 4-33, 4-67
  11432. gxStyleAttributes structure3-92
  11433. GXTouchesBoundsShape function4-47 to 4-51, 4-81
  11434. GXTouchesRectanglePoint function4-47 to 4-51, 4-80
  11435. GXTouchesShape function4-47 to 4-51, 4-82
  11436. GXUnionRectangle function4-88
  11437. GXUnionShape function4-56, 4-91
  11438. H
  11439.  
  11440. hairline dashes3-74
  11441. hairlines3-16
  11442. pixels included in3-16
  11443. halftoning
  11444. bitmaps5-28 to 5-29
  11445. hit-testing
  11446. picture shapes6-20, 6-40 to 6-45, 6-61
  11447. hollow frame fill
  11448. .See closed-frame shape fill2-5
  11449. I
  11450.  
  11451. If2-46
  11452. In4-29
  11453. inclusion
  11454. testing shapes for4-16 to 4-18, 4-51 to 4-53, 4-83 to 4-87
  11455. incorporating style information into shape geometries4-70
  11456. ink objects
  11457. of bitmap shapes5-7 to 5-8
  11458. overriding6-7 to 6-13, 6-33 to 6-35
  11459. insetting dashes3-69 to 3-70
  11460. insetting shapes4-45 to 4-47, 4-79
  11461. Inside2-89
  11462. inside frame style attribute3-18 to 3-19, 3-50 to 3-51, 3-69, 3-93
  11463. intersection
  11464. testing shapes for4-16 to 4-18, 4-47 to 4-51, 4-80 to 4-83
  11465. intersection operation4-19, 4-55, 4-87, 4-89
  11466. inverse shape fills2-13
  11467. inversion operation4-19, 4-59, 4-96
  11468. item depth6-45
  11469. item level6-45
  11470. J
  11471.  
  11472. join attributes3-96 to 3-97
  11473. join records3-95 to 3-96
  11474. joins3-25 to 3-27
  11475. adding to a shape3-58 to 3-61
  11476. curve3-96
  11477. effect of shape fill3-25, 3-95
  11478. functions for3-121 to 3-126
  11479. interactions with caps, dashes, patterns3-33 to 3-35, 3-86 to 3-90
  11480. level3-26, 3-60, 3-97
  11481. miter3-96
  11482. miter of3-27
  11483. sharp3-96
  11484. standard3-26, 3-61 to 3-63, 3-96 to 3-97
  11485. structure of join record3-95 to 3-96
  11486. join style property
  11487. functions for3-121 to 3-126
  11488. L
  11489.  
  11490. length of a shape4-38, 4-71
  11491. level caps3-24, 3-95
  11492. level dash attribute3-99
  11493. level dashes3-99
  11494. level join attribute3-97
  11495. level joins3-26, 3-60, 3-97
  11496. level of picture hierarchy6-45
  11497. Line2-8
  11498. line geometries2-8
  11499. definition of2-16
  11500. editing2-68 to 2-70, 2-105
  11501. replacing2-34 to 2-36
  11502. structure of2-91
  11503. line shapes2-8
  11504. converting other shapes to2-57 to 2-61
  11505. creating and drawing2-32 to 2-36
  11506. default2-16
  11507. definition of2-16
  11508. replacing geometries of2-34 to 2-36
  11509. M
  11510.  
  11511. map transform shape attribute4-44
  11512. effect on bitmaps5-10, 5-37
  11513. miter of joins3-27, 3-61 to 3-63, 3-96
  11514. multiple references in picture shapes6-9 to 6-12, 6-35 to 6-39
  11515. N
  11516.  
  11517. no-fill shape fill2-12
  11518. O
  11519.  
  11520. objects.See ink objects; shape objects; style objects; transform objects
  11521. off-curve control points
  11522. .See control points2-5
  11523. offscreen bitmaps5-42 to 5-49
  11524. open-frame shape fill2-12
  11525. compared to closed-frame shape fill2-21
  11526. compared to even-odd shape fill2-21
  11527. outsetting shapes4-47, 4-79
  11528. outside frame style attribute3-18 to 3-19, 3-51 to 3-53, 3-93
  11529. overlapping contours
  11530. effect of shape fill on2-55 to 2-57
  11531. removing4-29, 4-67
  11532. overriding inks6-7 to 6-13, 6-33 to 6-35
  11533. overriding styles6-7 to 6-13, 6-33 to 6-35
  11534. overriding transforms6-7 to 6-13, 6-33 to 6-35
  11535. P
  11536.  
  11537. path contours2-9
  11538. overlapping2-24
  11539. structure of2-93
  11540. path geometries
  11541. control bits2-23, 2-49
  11542. definition of2-23
  11543. editing2-68 to 2-70, 2-79 to 2-81, 2-114
  11544. path contours in2-50
  11545. structure of2-93
  11546. with multiple contours2-53 to 2-57
  11547. with only off-curve control points2-52 to 2-53
  11548. path shapes
  11549. approximating with polygon shapes3-43 to 3-46
  11550. converting other shapes to2-65 to 2-68
  11551. converting to polygon shapes3-43 to 3-46
  11552. creating and drawing2-49 to 2-57
  11553. default2-24
  11554. definition of2-23
  11555. effect of shape fill2-24, 2-54 to 2-57
  11556. with a single contour2-50 to 2-52
  11557. with crossed contours2-24
  11558. with multiple contours2-53 to 2-57
  11559. with only off-curve control points2-52 to 2-53
  11560. with overlapping contours2-53 to 2-57
  11561. pattern attributes3-100 to 3-101
  11562. as field of pattern record3-100
  11563. port align pattern attribute3-32, 3-101
  11564. port map pattern attribute3-32, 3-101
  11565. pattern grid3-100
  11566. pattern positions
  11567. determining3-83 to 3-85, 3-138
  11568. pattern record structures3-99 to 3-100
  11569. patterns3-31 to 3-32
  11570. adding to a shape3-81 to 3-83
  11571. aligning3-101
  11572. definition of pattern record structure3-99 to 3-100
  11573. determining pattern positions3-138
  11574. effect of shape fill3-31, 3-99
  11575. functions for3-132 to 3-139
  11576. grid3-100
  11577. interactions with caps, dashes, joins3-33 to 3-35, 3-86 to 3-90
  11578. mapping3-101
  11579. pattern positions3-83 to 3-85
  11580. pattern style property3-31
  11581. functions for3-132 to 3-139
  11582. pen
  11583. insetting3-50 to 3-51
  11584. outsetting3-51 to 3-53
  11585. pen placement3-18 to 3-21, 3-50 to 3-53
  11586. pen width3-15 to 3-17
  11587. pen width style property3-48 to 3-50
  11588. functions for3-112 to 3-116
  11589. phased dashes3-66
  11590. picture depth6-45
  11591. picture geometries
  11592. editing6-26 to 6-28, 6-55 to 6-59
  11593. properties of6-4
  11594. replacing6-26 to 6-28, 6-52 to 6-55
  11595. picture hierarchies6-14 to 6-15, 6-39 to 6-40
  11596. picture items
  11597. adding6-28 to 6-31
  11598. definition of6-4
  11599. multiple references to6-9 to 6-12, 6-35 to 6-39
  11600. removing6-31 to 6-33
  11601. replacing6-31 to 6-33
  11602. picture shapes
  11603. creating and drawing6-22 to 6-26, 6-50, 6-60
  11604. functions for6-50 to 6-63
  11605. hit-testing6-20, 6-40 to 6-45, 6-61
  11606. introduced1-17 to 1-19
  11607. pixel image5-4 to 5-7, 5-13 to 5-26
  11608. pixel size5-5 to 5-7, 5-13 to 5-26
  11609. point geometries2-8
  11610. definition of2-15
  11611. editing2-68 to 2-70, 2-103
  11612. replacing2-30 to 2-31
  11613. structure of2-90
  11614. point shapes2-8
  11615. converting other shapes to2-57 to 2-61
  11616. creating and drawing2-27 to 2-32
  11617. default2-15
  11618. definition of2-15
  11619. disposing2-31
  11620. replacing geometries of2-30 to 2-31
  11621. polgon shapes
  11622. effect of shape fill2-46 to 2-49
  11623. Polygon4-25
  11624. polygon contours2-9
  11625. definition of2-20
  11626. overlapping2-22, 2-45 to 2-49
  11627. structure of2-92
  11628. polygon geometries
  11629. definition of2-20
  11630. editing2-68 to 2-70, 2-71 to 2-78, 2-111
  11631. structure of2-92
  11632. polygon shape
  11633. definition of2-20
  11634. polygon shapes
  11635. converting other shapes to2-65 to 2-68
  11636. creating and drawing2-40 to 2-49
  11637. default2-23
  11638. effect of shape fill2-22
  11639. with a single contour2-41 to 2-43
  11640. with crossed contours2-22, 2-45 to 2-49
  11641. with multiple contours2-21, 2-44 to 2-45
  11642. port align pattern attribute3-32, 3-101
  11643. port map pattern attribute3-32, 3-101
  11644. primitive form
  11645. converting shapes to4-34 to 4-36, 4-70
  11646. primitive form of shapes3-9, 4-10
  11647. primitive shapes3-9, 4-8 to ??, 4-10, ?? to 4-14, 4-34 to 4-36, 4-70
  11648. Q
  11649.  
  11650. quadratic Bézier curves.See  Bezier curves2-5
  11651. QuickDraw4-14, 4-16, 4-19, 4-47, 4-51
  11652. R
  11653.  
  11654. rectangle geometries
  11655. definition of2-19
  11656. editing2-68 to 2-70, 2-109
  11657. structure of2-91
  11658. rectangle shapes
  11659. converting other shapes to2-57 to 2-61
  11660. creating and drawing2-36 to 2-38, ?? to 2-40
  11661. default2-20
  11662. definition of2-19
  11663. effect of shape fills2-37 to 2-38
  11664. reducing shapes4-8 to 4-14, 4-27 to 4-29, 4-66
  11665. reverse difference operation4-19, 4-57, 4-94
  11666. reversing contour direction4-21 to 4-25, 4-63
  11667. round caps3-56 to 3-58
  11668. S
  11669.  
  11670. scaled dashes3-65, 3-98
  11671. scaling shapes4-42 to 4-45, 4-77
  11672. shape attributes
  11673. map transform shape attribute4-44
  11674. shape fills2-10 to ??
  11675. definition of2-11
  11676. effect of contour direction4-21 to 4-25
  11677. effect on path shapes2-24, 2-55 to 2-57
  11678. effect on polygon shapes2-22
  11679. shape length to point4-38, 4-72
  11680. shapes
  11681. converting to primitive form4-34 to 4-36, 4-70
  11682. insetting4-45 to 4-47, 4-79
  11683. outsetting4-47
  11684. reducing4-27 to 4-29, 4-66
  11685. simplifying4-29 to 4-33, 4-67
  11686. testing for containment4-51 to 4-53, 4-83 to 4-87
  11687. testing for inclusion4-16 to 4-18, 4-51 to 4-53, 4-83 to 4-87
  11688. testing for intersection4-16 to 4-18, 4-47 to 4-51, 4-80 to 4-83
  11689. sharp join attribute3-96
  11690. sharp joins3-61 to 3-63, 3-96
  11691. simplifying shapes4-8 to 4-14, 4-29 to 4-33, 4-67
  11692. solid shape fills2-10
  11693. .See also even-odd shape fill;winding shape fill2-5
  11694. source grid style attribute3-21, 3-39 to 3-41, 3-93
  11695. square caps3-56 to 3-58
  11696. standard caps3-56 to 3-58
  11697. standard joins3-26, 3-61 to 3-63, 3-96 to 3-97
  11698. start caps3-53 to 3-56, 3-94
  11699. style attributes3-92 to 3-94
  11700. auto-inset style attribute3-93
  11701. center frame style attribute3-93
  11702. device grid style attribute3-41 to 3-43, 3-93
  11703. inside frame style attribute3-69, 3-93
  11704. outside frame style attribute3-93
  11705. source grid style attribute3-39 to 3-41, 3-93
  11706. style objects
  11707. associating with shape objects3-36 to 3-39
  11708. cap property3-24
  11709. caps property
  11710. 3-53 to 3-56
  11711. dash property3-27
  11712. 3-63 to 3-66
  11713. default3-13 to 3-14
  11714. definition of3-5
  11715. geometric properties of3-91 to 3-92
  11716. incorporating into shape geometries4-34 to 4-36, 4-70
  11717. joins property
  11718. 3-58 to 3-61
  11719. of bitmap shapes5-7
  11720. overriding6-7 to 6-13, 6-33 to 6-35
  11721. pattern property3-31
  11722. 3-81 to 3-83
  11723. relationship to shape objects3-5
  11724. shared among shape objects3-7
  11725. style attributes property3-92 to 3-94
  11726. style properties of geometric shapes3-12 to 3-13, 3-91 to 3-92
  11727. cap style property3-116 to 3-121
  11728. curve error style property3-43 to 3-46, 3-46 to 3-48, 3-107 to 3-112
  11729. dash style property3-126 to 3-132
  11730. definition3-5
  11731. join style property3-121 to 3-126
  11732. pattern style property3-132 to 3-139
  11733. pen width style property3-48 to 3-50, 3-112 to 3-116
  11734. T
  11735.  
  11736. text
  11737. using as dashes3-75 to 3-76
  11738. The2-12, 2-17, 5-60
  11739. transfer modes
  11740. effect on bitmap shapes5-8, 5-30 to ??
  11741. transform concatenation6-15 to 6-19, 6-39 to 6-40
  11742. transform objects
  11743. concatenating6-15 to 6-19, 6-39 to 6-40
  11744. of bitmap shapes5-8 to 5-10
  11745. overriding6-7 to 6-13, 6-33 to 6-35
  11746. true inside of a contour4-8
  11747. type conversion
  11748. definition of2-57
  11749. to curve shapes2-61 to 2-65
  11750. to line shapes2-57 to 2-61
  11751. to path shapes2-65 to 2-68
  11752. to point shapes2-57 to 2-61
  11753. to polygon shapes2-65 to 2-68
  11754. to rectangle shapes2-57 to 2-61
  11755. U
  11756.  
  11757. union operation4-19, 4-56, 4-88, 4-91
  11758. unique items attribute6-13 to 6-14, 6-37 to 6-39
  11759. V
  11760.  
  11761. view devices
  11762. and bitmap shapes5-10 to 5-12, 5-42 to 5-47
  11763. W
  11764.  
  11765. winding-number rule for filling shapes2-12
  11766. winding shape fill2-48, 2-55, 2-57
  11767. compared to even-odd shape fill2-22
  11768. defined2-13
  11769. introduced2-11
  11770. wrapping text to a contour3-75 to 3-76
  11771. Y
  11772.  
  11773. You4-67
  11774. This Apple manual was written, edited, and composed on a desktop publishing system using Apple Macintosh computers and FrameMaker software. Proof pages were created on an Apple LaserWriter Pro printer. Final page negatives were output directly from text files on an Optrotech SPrint 220 imagesetter. Line art was created using Adobe™ Illustrator and Adobe Photoshop. PostScript™, the page-description language for the LaserWriter, was developed by Adobe Systems Incorporated.
  11775. Text type is Palatino® and display type is Helvetica®. Bullets are ITC Zapf Dingbats®. Some elements, such as program listings, are set in Apple Courier.
  11776. WRITER
  11777. Marq T. Laube
  11778. DEVELOPMENTAL EDITORS
  11779. Laurel Rezeau, George Truett
  11780. ILLUSTRATORS
  11781. Ruth Anderson, Sandee Karr, Mai-Ly Pham
  11782. PRODUCTION EDITORS
  11783. Tess Lujan, Josephine Manuele
  11784. PROJECT MANAGER
  11785. Trish Eastman
  11786. LEAD WRITER
  11787. David Bice
  11788. LEAD EDITOR
  11789. Laurel Rezeau
  11790. ART DIRECTOR/COVER DESIGNER
  11791. Barbara Smyth
  11792. Special thanks to Pete Alexander, Cary Clark, Dave Good, Josh Horwich, Rob Johnson, David Surovell, Chris Yerga
  11793. Acknowledgments to Sarah Chester, Gary Hillerson, Gary McCue, Diane Patterson, Rich Pettijohn, Laine Rapin
  11794. 8@ˇ ˇˇˇˇ@
  11795. ˇ·ˇ‚7^
  11796. 4í∫◊, Palatino
  11797. .°dONLNdˇˇ(ô∫    Addison-WÑ@°dONLNdˇˇ)4esley Publishing Company
  11798.     °dONLNdˇˇ(´∫Reading, MassachusettsÀ†°dONLNdˇˇ)hMenlo Park, California쇰dONLNdˇˇ)dNew ˆ∞°dONLNdˇˇ)Y#°dONLNdˇˇ)ork°dONLNdˇˇ(∑∫Don Mills, Ontarioc °dONLNdˇˇ)TW膰dONLNdˇˇ)okingham, England@°dONLNdˇˇ)XAmsterܰdONLNdˇˇ)damwp°dONLNdˇˇ)Bonn°dONLNdˇˇ(√∫SydneyH °dONLNdˇˇ)'Singapor°dONLNdˇˇ)$ee∞°dONLNdˇˇ)
  11799. T°dONLNdˇˇ)okyoÏP°dONLNdˇˇ)Madrid–°dONLNdˇˇ)(San Juan°dONLNdˇˇ(œ∫Parisl¿°dONLNdˇˇ)Seoulk`°dONLNdˇˇ)MilanËİdONLNdˇˇ)  Mexico City °dONLNdˇˇ):T»Ä°dONLNdˇˇ)aipei
  11800. (0∫4Ÿ∫˘
  11801. {∂èÕ4zµ{∂ê{∂èÕ08x|˛˛ˇˇ?ˇ¯?ÔÔ«‡á‡É¿¿Äê{∂èÕ08||«‡É¿¿ÄÄ
  11802. ˇ·ˇ‚7^
  11803. 3 ðdONLNdí∫´‘*t
  11804. INSIDE MACINT∫ °dONLNd
  11805. í‘´(§‘OSH
  11806. ˙H 4˚H  H
  11807. ˇ·ˇ‚7^
  11808. ˇˇ≥>ˇ◊°dONLNd
  11809. H.è(&HQuickDraw GX Graphicsˇ#@ˇ ˇˇˇˇ@
  11810. ˇ·ˇ‚7^
  11811. 4⁄ú˙¯,     Helvetica
  11812. .(ÔúDraft. PreliminaryVP):, Confi)
  11813. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/15/93 X*XÙ4^*.∫, Palatino
  11814. °dONLNdZ*f1(c*
  11815. °dONLNd\6er) Apple Computer>İdONLNd\reÇ)<, Inc.°dONLNdg*pC(n*© 1994 .İdONLNdgDpÄ)Apple Computer̰dONLNd,gpè);, Inc.°dONLNd3p*yP(w* All rights r˝Ä°dONLNd?pPyo)&    eserved. °dONLNdI{*Ñ•(Ç*#No part of this publication may be °dONLNdlÑ*ç-*    rÑİdONLNdmÑ-ç8)epr-°dONLNdpÑ9çd) oduced, storËİdONLNd|ÑdçÄ)+    ed in a r°°dONLNdÖÑÅçù)    etrieval °dONLNdéç*ñ≤(î*'system, or transmitted, in any form or °dONLNdµñ*üû*     by any means, mechanical, electréİdONLNd’ñûü∞)tonic, °dONLNd€ü*®b(¶*photocopying, rÔİdONLNdÍüb®p)8ecor¥°dONLNdÓüq®µ)ding, or otherwise, °dONLNd®*±™(Ø*$without prior written permission of °dONLNd&±*∫f*    Apple Computer>İdONLNd4±f∫´)<, Inc. Printed in the °dONLNdJ∫*√d(¡*United States of iİdONLNd[∫d√Ñ):America.°dONLNdd≈*Œf(Ã*No licenses, exprúİdONLNdu≈fŒ¢)<ess or implied, arX°dONLNdá≈£Œ®)=e °dONLNdâŒ*◊](’*granted with r`İdONLNdóŒ]◊£)3espect to any of the °dONLNd¨◊*‡•(fi*#technology described in this book. °dONLNdœ‡*ÈE*    Apple rÑİdONLNd÷‡EÈó)etains all intellectual pr °dONLNd‡òȱ)Soperty °dONLNd˜È*ÚØ(*&rights associated with the technology °dONLNdÚ*˚®*    %described in this book. This book is °dONLNdB˚*ì*    intended to assist application °dONLNda*
  11816. π*    (developers to develop applications only °dONLNdâ
  11817. *6*    for eİdONLNdç
  11818. 6ú) Apple Macintosh computers.°dONLNd®*!G(*Every ef≥İdONLNd∞G!©)fort has been made to ensurΔ°dONLNdÀ©!Æ)be °dONLNdÕ!**Ø((*'that the information in this manual is °dONLNdÙ**3K*    
  11819. accurate. ªÄ°dONLNd˛*K3{)!Apple is not r°dONLNd *|3Ø)1esponsible for °dONLNd3*<w(:*printing or clerical errİdONLNd33x<Ñ)Nors.°dONLNd8@*If(G*Apple Computer>İdONLNdF@fIv)<, Inc.°dONLNdMI*R^(P*20525 Mariani >İdONLNd[I^Rd)4AªÄ°dONLNd\IcRx)venue°dONLNdbR*[^(Y*
  11820. Cupertino, CA6İdONLNdoR^[t)4 95014°dONLNdv[*dW(b* 408-996-1010°dONLNdÉh*qQ*
  11821. Apple, the MİdONLNdéhQqó)'Apple logo, LaserW~°dONLNd†hóq¶)Friter˝Ä°dONLNd•h•q∏), and °dONLNd´q*zX(x* Macintosh ar§Ä°dONLNd∑qXzë).e trademarks of √°dONLNd«qëz©)9Apple °dONLNdÕz*ÉN(Å*Computer>İdONLNd’zNÉf)$    , Inc., r*°dONLNdfizfÉ})egisterüİdONLNdÂz}É∏)ed in the United °dONLNdˆÉ*åá(ä*States and other countries.°dONLNdé*óg* Adobe IllustratorİdONLNd#égók)=, “°dONLNd%éjó≠)Adobe Photoshop, °dONLNd6ó*†f(û*and PostScript arÍİdONLNdGóf†ü)<e trademarks of     °dONLNdWó††π):Adobe °dONLNd]†*©Æ(ß*#Systems Incorporated, which may be °dONLNdÄ©*≤-*    rÑİdONLNdÅ©-≤D)egister˙°dONLNdà©D≤ü)ed in certain jurisdictions.°dONLNd•¥*Ωj(ª*FrameMaker is a røÄ°dONLNd∂¥jΩÅ)@egister5°dONLNdΩ¥ÇΩ≥)
  11822. ed trademark °dONLNd Ω*ΔP(ƒ*
  11823. of Frame T4°dONLNd‘ΩPΔ§)&echnology Corporation.°dONLNdλ*—É(œ*Helvetica and Palatino ar÷İdONLNd»É—ã)Ye r∞°dONLNd»å—£)    egister%İdONLNd»§—Æ)ed °dONLNd—*⁄¢(ÿ*trademarks of Linotype Company&°dONLNd/—¢⁄§)x.°dONLNd1‹*Â(„*ITC Zapf Dingbats is a r]İdONLNdI‹Âñ)Uegister”°dONLNdP‹ñ†)ed °dONLNdSÂ*Óé(Ï*trademark of International TΔ°dONLNdoÂéÓ´)dypeface °dONLNdwÓ*˜W(ı* Corporation.°dONLNdÑ˘*:* Optr9İdONLNdà˘;∞)!otech is a trademark of Orbotech °dONLNd©* W(    * Corporation.°dONLNd∂*π*
  11824. 'Simultaneously published in the United °dONLNd›*!m*    States and Canada.4^….Y
  11825. °dONLNd]…eÒ(c…    LIMITED W°dONLNd˘]Òe=)(ARRANTY ON MEDIAöp°dONLNd    ]=eQ)L AND °dONLNdf…nˇ(l… REPLACEMENT°dONLNds…{÷*
  11826. ALL_0°dONLNds◊{)
  11827.  IMPLIED WYê°dONLNd's{M))ARRANTIES ON THIS °dONLNd9|…Ñ<(Ç…MANUAL, INCLUDING IMPLIED °dONLNdSÖ…ç–*    Wfl°dONLNdTÖœç2)ARRANTIES OF MERCHANTd°dONLNdiÖ2çP)cABILITY °dONLNdqé…ñ(î…AND FITNESS FOR AÊ∞°dONLNdÇéñ)H Ph¿°dONLNdÑéñ!)ARÜP°dONLNdÜé!ñC)
  11828. TICULAR °dONLNdéó…ü?(ù…PURPOSE, ARE LIMITED IN DURA¶ °dONLNd™ó?üS)vTION °dONLNd؆…® (¶…TO NINETY (90) DAiİdONLNd¿† ®I)BYS FROM THE DAÀ†°dONLNdŒ†H®R)=TE °dONLNd—©…±
  11829. (Ø…OF THE ORIGINAL∞°dONLNd‡© ±)B RET30°dONLNd‰©±&)AILÖ °dONLNdÁ©&±Q)
  11830.  PURCHASE °dONLNdÒ≤…∫ (∏…OF THIS PRODUCTæ`°dONLNd≤ ∫ )B.°dONLNdø…«B(≈…$Even though Apple has reviewed this °dONLNd&»…–-*    manual, APPLE MAKES NO Wa@°dONLNd>»-–R)dARRANTY °dONLNdF—…Ÿˇ(◊… OR REPRESENT{¿°dONLNdR—ˇŸ)6AI °dONLNdS—ŸW)TION, EITHER EXPRESS °dONLNdh⁄…‚O(‡…!OR IMPLIED, WITH RESPECT TO THIS °dONLNdâ„…Î*    MANUAL, ITS QUALITYf∞°dONLNdú„ÎH)S
  11831. , ACCURACYõİdONLNd¶„HÎK),, °dONLNd®Ï…ÙÙ(Ú…MERCHANT°dONLNd∞ÏÙÙ)+ABILITY≠p°dONLNd∑ÏÙU), OR FITNESS FOR A[†°dONLNd…ÏVÙW)F °dONLNd ı…˝Õ(˚…PB°dONLNdÀıÕ˝◊)AR_†°dONLNdÕı◊˝/)
  11832. TICULAR PURPOSE. AS AÑê°dONLNd‚ı/˝H)X RESUL‡°dONLNdËıH˝L)T†°dONLNdÈıL˝O), °dONLNdβ…˝(… THIS MANUAL°dONLNdˆ˛˛N)5 IS SOLD “AS IS,” AND °dONLNd …X(
  11833. …!YOU, THE PURCHASER, ARE ASSUMING °dONLNd-…Q*    "THE ENTIRE RISK AS TO ITS QUALITY °dONLNdO…!*     AND ACCURACY0°dONLNd[!)<.°dONLNd]&….
  11834. (,…IN NO EVENT WILLùp°dONLNdm&
  11835. .M)D APPLE BE LIABLE °dONLNd~/…7ı(5…
  11836. FOR DIRECTˇ@°dONLNdà/Ù7)+
  11837. , INDIRECT °dONLNdí/7A)( , SPECIAL, °dONLNdù8…@Ì(>…INCIDENTÃİdONLNd•8Ì@F)$AL, OR CONSEQUENTIALK°dONLNdπ8G@H)Z °dONLNd∫A…I(G…
  11838. DAMAGES RESUL)–°dONLNd«AIF)?TING FROM ANY °dONLNd’J…RD(P…DEFECT OR INACCURACY IN THIS °dONLNdÚS…[X*    +MANUAL, even if advised of the possibility °dONLNd    \…dˇ*    of such damages.°dONLNd    .i…q‡*
  11839. THE We†°dONLNd    3i‡qO)ARRANTY AND REMEDIES SET °dONLNd    Lr…z◊(x…FOR°dONLNd    Or◊zV)TH ABOVE ARE EXCLUSIVE AND IN °dONLNd    m{…ÉÙ(Å… LIEU OF ALLQ°dONLNd    x{ıÉ,),
  11840.  OTHERS, ORAL¸†°dONLNd    Ö{,É:)7 OR °dONLNd    âÑ…åJ(ä… WRITTEN, EXPRESS OR IMPLIED. No °dONLNd    ©ç…ïÚ*     Apple dealerÜ0°dONLNd    µçÚï:)), agent, or employee is °dONLNd    Õñ…û+(ú…authorized to make any modifi°dONLNd    Íñ+ûA)bcation, °dONLNd    Úü…ßC(•…'extension, or addition to this warrantyÛ`°dONLNd
  11841. üBßC)y.°dONLNd
  11842. ¨…¥N(≤…*Some states do not allow the exclusion or °dONLNd
  11843. Eµ…ΩU*    .limitation of implied warranties or liability °dONLNd
  11844. sæ…ΔU*    ,for incidental or consequential damages, so °dONLNd
  11845. ü«…œO*    *the above limitation or exclusion may not °dONLNd
  11846. …–…ÿC*    &apply to you. This warranty gives you °dONLNd
  11847. ÔŸ…·›*    specifi¿°dONLNd
  11848. ˆŸfi·T)&c legal rights, and you may also have °dONLNd ‚…ÍO(Ë…,other rights which vary from state to state.4^h.¯4d*¬∫
  11849. °dONLNd Ib*kr(i*ISBN 0-201-nnnnn-n°dONLNd \k*tk*    1 2 3 4 5 6 7 8 9-CR‚İdONLNd pkkts)AWr°dONLNd qkstù) -9897969594°dONLNd }t*}Ü({*First Printing, Month 19944d…¬¯ˇä@ˇ ˇˇˇˇ@
  11850. ˇ·ˇ‚7^
  11851. 4⁄∫˙, Palatino
  11852. .Ñ`(‡ iii,     Helvetica
  11853. (Ô∫Draft. PreliminaryVP):, Confi)
  11854. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/20/934^H¿
  11855. ^Hö4^Hö
  11856. °dONLNd^∫w(p∫Contents
  11857. ˇ·ˇ‚7^
  11858. °dONLNd    ò∫§“*1FigurR¿°dONLNdò“§Ê)es, Tè °dONLNdò§6)ables, and Listings|@°dONLNd(òK§S)fxi
  11859. ¬H…4√H… ƒHƒ
  11860. ˇ·ˇ‚7^
  11861. °dONLNd+∂H¡m(æHPreface
  11862. °dONLNd3≥∫¬‚)rAbout ∑@°dONLNd9≥‚¬ )(    This Book
  11863. Û@°dONLNdDµ4¡A)Rxxi°dONLNdI…∫’ˆ(“∫ What to Readfl°dONLNdW…
  11864. ’)Pxxi°dONLNd[÷∫‚Ï(fl∫
  11865. Chapter Orä°dONLNde÷Ï‚)2
  11866. ganizationDİdONLNdq÷/‚?)Cxxii°dONLNdv„∫ÔE(Ï∫Conventions Used in This BookİdONLNdï„ZÔj)†xxii°dONLNdöƒ¸˛(˘ƒ
  11867. Special Fonts°‡°dONLNd©¸%)Nxxiii°dONLNdØ˝ƒ     (ƒT∫¿°dONLNd∞˝…    )
  11868. ypes of Notes)`°dONLNdø˝    -)Qxxiii°dONLNd≈
  11869. ƒ(ƒNumerical Formatsq‡°dONLNdÿ
  11870. .A)jxxiii°dONLNdfiƒ#˘( ƒ
  11871. Illustrations◊°dONLNdÌ
  11872. # )Ixxiii°dONLNdÛ$∫0(-∫Development EnvirH‡°dONLNd$02)WonmentA °dONLNd $G0Y)6xxiv°dONLNd1∫=Ù(:∫ Developer Pr·†°dONLNd1Ù=K):oducts and SupportL`°dONLNd11`=r)lxxiv
  11873. mHt4nHt oHo
  11874. ˇ·ˇ‚7^
  11875. °dONLNd6aHlx(iH    Chapter 1
  11876. °dONLNd@^∫m^)rIntroduction to QuickDraw h °dONLNdZ^_mØ)• GX Graphics
  11877. á°dONLNdg`√l–)d1-1°dONLNdlt∫ÄG(}∫About QuickDraw GX Graphics)°dONLNdât\Äi)¢1-3°dONLNdçÅ∫ç    (ä∫Geometric Shapes%`°dONLNdüÅç+)d1-6°dONLNd£éƒö(óƒGeometric Shape T£ °dONLNd¥éö+)Sypes;°dONLNd∫é@öM))1-6°dONLNdæõƒßD(§ƒGeometric Shape Geometries
  11878. @°dONLNd⁄õYßf)ï1-7°dONLNdfi®ƒ¥$(±ƒGeometric Shape Fills̆°dONLNdı®8¥E)t1-8°dONLNd˘µƒ¡E(æƒGeometric Styles, Inks, and T؆°dONLNdµD¡p)Ä    ransforms}†°dONLNd!µÖ¡í)A1-9°dONLNd%¬ƒŒ%(ÀƒGeometric OperationsT`°dONLNd;¬:ŒG)v1-1†°dONLNd>¬GŒL)
  11879. 1°dONLNd@œ∫€˚(ÿ∫
  11880. Bitmap Shapes6İdONLNdOœ€")V1-15°dONLNdT‹∫Ë‘(Â∫Pictur¿°dONLNdZ‹‘Ë˙)e ShapesT@°dONLNdd‹Ë!);1-17
  11881. H4H H
  11882. ˇ·ˇ‚7^
  11883. °dONLNdi Hx(H    Chapter 2
  11884. °dONLNds    ∫-)rGeometric Shapes
  11885. i°dONLNdÖ BO)à2-1°dONLNdä∫+(((∫About Geometric Shapes≥@°dONLNd¢<+I)Ç2-5°dONLNd¶,ƒ8(5ƒThe Geometric Pr‡°dONLNd∂,8Ä)Noperties of Shape Objects‡°dONLNd—,ï8¢)É2-7°dONLNd’9ŒEÒ(BŒShape T†°dONLNd‹9ÒE)#yperİdONLNd·9E")$2-7°dONLNdÂFŒR(OŒShape Geometry‡°dONLNdıF,R9)^2-8°dONLNd˘SŒ_˘(\Œ
  11886. Shape Fill% °dONLNdS_ )@2-10°dONLNd
  11887. `ƒl+(iƒThe Geometric Shape Tfi‡°dONLNd`*l>)fypesv¿°dONLNd%`Sle))2-14°dONLNd*mŒyV(vŒEmpty Shapes and Full ShapesÀ@°dONLNdHmjy|)ú2-15°dONLNdMzŒÜ(ÉŒ Point Shapesï °dONLNd[zÜ-)M2-15°dONLNd`áŒì(êŒ Line Shapesπ°dONLNdmáì))I2-16°dONLNdr (ùŒ Curve ShapesöİdONLNdÄî†1)Q2-17°dONLNdÖ°Œ≠(™ŒRectangle ShapesV†°dONLNdó°/≠A)a2-19°dONLNdúÆŒ∫(∑ŒPolygon ShapesÊİdONLNd¨Æ(∫:)Z2-20ˇN@ˇ ˇˇˇˇ@
  11888. ˇ·ˇ‚7^
  11889. 4⁄*ˇ¯, Palatino
  11890. .(·*iv,     Helvetica
  11891. +rDraft. PreliminaryVP):, Confi)
  11892. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/20/934^*¿¯
  11893. °dONLNd\∞hÂ(e∞ Path Shapes7@°dONLNd
  11894. \˙h )J2-23°dONLNdiúu(rúUsing Geometric ShapesÚİdONLNd*iu.)Ä2-25°dONLNd/v¶Ç±(¶Cr\°dONLNd1v±Çî) /eating and Drawing Empty Shapes and Full Shapesπ°dONLNdbv®Ç∫)˜2-26°dONLNdgɶè±(å¶Cr\°dONLNdiɱè') eating and Drawing Points&°dONLNdÑÉ<èN)ã2-27°dONLNdâê¶ú±(ô¶Cr\°dONLNdãê±ú#) eating and Drawing LinesI‡°dONLNd•ê8úJ)á2-32°dONLNd™ù¶©±(¶¶Cr\°dONLNd¨ù±©;) eating and Drawing RectanglesÁİdONLNdÀùO©a)û2-36°dONLNd–™¶∂±(≥¶Cr\°dONLNd“™±∂+) eating and Drawing Curves+`°dONLNdÌ™@∂R)è2-39°dONLNdÚ∑¶√±(¿¶Cr\°dONLNdÙ∑±√5) eating and Drawing Polygonsw`°dONLNd∑I√[)ò2-40°dONLNdƒ∞–ª(Õ∞Cr\°dONLNdƒª–) eating Polygons W-‡°dONLNd)ƒ–f)Sith a Single ContourÙ °dONLNd?ƒz–å)l2-41°dONLNdD—∞›ª(⁄∞Cr\°dONLNdF—ª›) eating Polygons W-‡°dONLNdW—›n)Sith Mulitple Contours∫ °dONLNdn—Ç›î)t2-44°dONLNdsfi∞ͪ(Á∞Cr\°dONLNdufiªÍ) eating Polygons W-‡°dONLNdÜfiÍ')Sith CrܰdONLNdåfi'Ík)ossed Contours'`°dONLNdúfiÄÍí)Y2-45°dONLNd°Î¶˜±(Ù¶Cr\°dONLNd£Î±˜$) eating and Drawing Paths» °dONLNdΩÎ8˜J)á2-49°dONLNd¬¯∞ª(∞Cr\°dONLNdƒ¯ª˝) eating Paths W~†°dONLNd“¯˝U)Bith a Single ContourD‡°dONLNd˯j|)m2-50°dONLNdÌ∞ª(∞Cr\°dONLNdÔª4) eating Paths Using Only Of@°dONLNd    4t)yf-Curve Pointsfl‡°dONLNdàö)T2-52°dONLNd∞ª(∞Cr\°dONLNd ª˝) eating Paths W~†°dONLNd.˝])Bith Multiple Contours
  11895. ‡°dONLNdErÑ)u2-53°dONLNdJ¶+à((¶2Converting Shapes to Points, Lines, and Rectanglesò†°dONLNd~ú+Æ)ˆ2-57°dONLNdÉ,¶8D(5¶!Converting Shapes to Curve Shapes7‡°dONLNd¶,Y8k)≥2-61°dONLNd´9¶E^(B¶'Converting Shapes to Polygons and PathsnİdONLNd‘9sEÖ)Õ2-65°dONLNdŸF¶R (O¶Replacing Geometric Points_°dONLNdıF5RG)è2-68°dONLNd˙S¶_(\¶Editing Polygon Partss`°dONLNdS_-)u2-71°dONLNd`¶l˙(i¶Editing Paths Parts °dONLNd+`l!)i2-79°dONLNd0m¶y˝(v¶Editing Shape PartsɆ°dONLNdEmy#)k2-81°dONLNdJzúÜN(Éú%Applying Functions Described ElsewherP@°dONLNdozOܱ)≥e to Geometric Shapesw °dONLNdÜz≈Ü◊)v2-86°dONLNdãá¶ì(ê¶Shape-Related Functions `†°dONLNd£áì£)pApplicable to Geometric Shapes°dONLNd√á∏ì )¢2-86°dONLNd»î¶†
  11896. (ù¶Geometric Operations v°dONLNd›î
  11897. †ó)dApplicable to Geometric Shapes`°dONLNd˝î¨†æ)¢2-88°dONLNd°¶≠(™¶Style-Related Functions G°dONLNd°≠û)kApplicable to Geometric ShapesÍ`°dONLNd:°≤≠ƒ)°2-89°dONLNd?ƶ∫
  11898. (∑¶Ink-Related Functions B¿°dONLNdUÆ
  11899. ∫ó)dApplicable to Geometric ShapesÊ °dONLNduÆ´∫Ω)°2-89°dONLNdzª¶«¨(ƒ¶T∫¿°dONLNd{ª´«()ransform-Related Functions OİdONLNdñª)«∂)~Applicable to Geometric ShapesÚ‡°dONLNd∂ª «‹)°2-89°dONLNdª»ú‘(—úGeometric Shapes ReferˇÄ°dONLNd—»‘)ience‘`°dONLNd◊»-‘?)(2-89°dONLNd‹’¶·√(fi¶Data T:`°dONLNd‚’√·◊)ypes“@°dONLNd˒η˝)(2-90°dONLNdÌ‚∞Ó÷(Î∞    Point Str‹°dONLNdˆ‚÷ÓÌ)&uctura‡°dONLNd˚‚ÓÓÚ)e+İdONLNd˛‚Ó)2-90°dONLNdÔ∞˚“(¯∞Line Strˇ‡°dONLNd Ô“˚È)"ucturÖ¿°dONLNdÔÍ˚Ó)eO`°dONLNdÔ˚)2-91°dONLNd¸∞œ(∞Curves=†°dONLNd ¸‰ˆ)42-91°dONLNd%    ∞Í(∞
  11900. Rectangle StrùİdONLNd2    Í):uctur#`°dONLNd7    )ḛdONLNd:    ,)2-91°dONLNd?∞"„(∞ Polygon Str-`°dONLNdJ‰"˚)4uctur≥@°dONLNdO˚")esπ‡°dONLNdS"*)2-92°dONLNdX#∞/”(,∞Path Str~ °dONLNd`#”/Í)#uctur°dONLNde#Î/Ù)es
  11901. †°dONLNdi#/)2-93°dONLNdn0¶<—(9¶    FunctionsİdONLNdy0Ê<¯)@2-94°dONLNd~=∞Iª(F∞Cr\°dONLNdÄ=ªI() eating Geometric Shapes÷@°dONLNdô=<IN)Å2-94°dONLNdûJ∞VX(S∞$Getting and Setting Shape Geometries˚@°dONLNdƒJlVÉ)º2-102°dONLNd W∞c#(`∞Editing Shape Geometries©‡°dONLNd‰W7cD)á2-1q °dONLNdÁWDcN)
  11902. 15°dONLNdÍd∞p)(m∞Drawing Geometric Shapesı °dONLNdd=pT)ç2-134°dONLNd
  11903. qú}$(zúSummary of Geometric Shapes_`°dONLNd'q9}P)ù2-139°dONLNd-~∞ä(á∞Constants and Data TUİdONLNdA~ä#)_ypesÌ`°dONLNdG~7äN)(2-139°dONLNdMã∞ó€(î∞    FunctionsİdONLNdXãó)@2-140ˇ.@ˇ ˇˇˇˇ@
  11904. ˇ·ˇ‚7^
  11905. 4⁄∫˙, Palatino
  11906. .‡(‡v,     Helvetica
  11907. (Ô∫Draft. PreliminaryVP):, Confi)
  11908. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/20/934^H¿
  11909. kHr4lHr mHm
  11910. ˇ·ˇ‚7^
  11911. °dONLNd_Hjx(gH    Chapter 3
  11912. °dONLNd
  11913. \∫k$)rGeometric Styles
  11914. °dONLNd^9jF)3-1°dONLNd!r∫~#({∫About Geometric Stylesô†°dONLNd9r7~D)}3-5°dONLNd=ƒã(àƒShapes and Stylesá@°dONLNdP'ã4)c3-5°dONLNdTåƒò/(ïƒIncorporating Stylistic Vч°dONLNdmå/òº)kariations Into Shape Geometriesı°dONLNdéå–ò›)°3-9°dONLNdíôƒ•Ê(¢ƒStyle Pr뇰dONLNdöôÊ•    )"operties˜ °dONLNd§ô•/)73-12°dONLNd©¶ƒ≤ (؃Default Style Objects√`°dONLNd¿¶4≤F)p3-13°dONLNd≈≥ƒø(ºƒ    Curve ErrT°dONLNdŒ≥ø˘),orº °dONLNd“≥
  11915. ø)3-14°dONLNd◊¿ƒÃ(…ƒThe Geometric Pen·°dONLNdÍ¿,Ã>)h3-15°dONLNdÔÕƒŸ‹(÷ƒStyle d‡°dONLNdıÕ‹Ÿ)
  11916. Attributesc†°dONLNdÕŸ/)A3-17°dONLNd⁄ŒÊ(„Œ
  11917. Pen PlacementҰdONLNd⁄#Ê5)U3-18°dONLNdÁŒÛÊ(ŒGridsT‡°dONLNd!Á˚Û
  11918. )-3-21°dONLNd&ÙƒT(˝ƒ Caps, Joins, Dashes and PatternsƆ°dONLNdHÙhz)§3-22°dONLNdMŒ
  11919. ‰(
  11920. ŒCaps÷ °dONLNdS¯
  11921. 
  11922. )*3-23°dONLNdXŒ„(ŒJoins@ °dONLNd_¯
  11923. )*3-25°dONLNddŒ'Ì($ŒDashesR@°dONLNdl')43-27°dONLNdq(Œ4Ú(1ŒPatternsŸ°dONLNd{(4)83-31°dONLNdÄ5ŒAø(>Œ6Interactions Between Caps, Joins, Dashes, and Patterns_`°dONLNd∏5‘AÊ(>‘3-33°dONLNdΩB∫N!(K∫Using Geometric Stylesÿ‡°dONLNd’B5NG){3-35°dONLNd⁄Oƒ[ (XƒAssociating Styles Wé@°dONLNdÓO [M)\
  11924. ith Shapes$@°dONLNd˙Ob[t)B3-36°dONLNdˇ\ƒhv(eƒ&Constraining Shape Geometries to Grids^°dONLNd'\ãhù)«3-39°dONLNd,iƒuf(rƒ#Constraining Shapes to Device GridsHİdONLNdQi{uç)∑3-41°dONLNdVvƒÇG(ƒConverting Paths to PolygonsgİdONLNdtv\Çn)ò3-43°dONLNdyɃè (åƒUsing Curve Err! °dONLNdàÉ
  11925. èÅ)Ior When Reducing Shapes„ °dONLNd°Éïèß)à3-46°dONLNd¶êƒú (ôƒManipulating Pen WC‡°dONLNd∏ê úu)\idth and Placement& °dONLNdÃêäúú)j3-48°dONLNd—ùƒ©/(¶ƒAdding Caps to a Shape≤İdONLNdÈùC©U)3-53°dONLNdÓ™ƒ∂ (≥ƒAdding Standar{‡°dONLNd¸™ ∂Z)Gd Caps to a ShapeÇİdONLNd™n∂Ä)c3-56°dONLNd∑ƒ√.(¿ƒAdding Joins to a ShapeİdONLNd-∑C√U)3-58°dONLNd2ƒƒ– (ÕƒAdding Standar{‡°dONLNd@ƒ –Y)Gd Joins to a ShapeÏİdONLNdTƒm–)b3-61°dONLNdY—ƒ›
  11926. (⁄ƒDashing a Shapeq`°dONLNdj—"›4)^3-63°dONLNdofiƒÍW(Áƒ Adjusting Dashes to Fit Contours†°dONLNdëfilÍ~)®3-67°dONLNdñ΃˜
  11927. (ÙƒInsetting Dashes÷`°dONLNd®Î!˜3)]3-69°dONLNd≠¯ƒŒ(ƒBr`¿°dONLNdدŒH)
  11928. eaking and Bending Dashes] °dONLNd ¯]o)è3-71°dONLNdœƒŒ(ƒW¬†°dONLNd–Õ¯)        rapping T∏ °dONLNdŸ¯)+extÏ¿°dONLNdfi+)!3-75°dONLNd„ƒ@(ƒDetermining Dash Positions˙‡°dONLNdˇTf)ê3-77°dONLNdƒ+@((ƒAdding a Pattern to a Shape¯`°dONLNd!T+f)ê3-81°dONLNd&,ƒ8I(5ƒDetermining Pattern PositionsK@°dONLNdE,^8p)ö3-83°dONLNdJ9ƒEã(Bƒ+Combining Caps, Joins, Dashes, and Patternsô`°dONLNdw9üE±)€3-86°dONLNd|F∫R(O∫Geometric Styles Refer‡°dONLNdíFR1)dence∫¿°dONLNdòFFRX)(3-90°dONLNdùSƒ_#(\ƒConstants and Data TUİdONLNd±S#_7)_ypesÌ`°dONLNd∑SK_])(3-91°dONLNdº`Œl(iŒ
  11929. Style Objects6¿°dONLNdÀ`l-)M3-91°dONLNd–mŒyÊ(vŒStyle d‡°dONLNd÷mÊy)
  11930. Attributesc†°dONLNd‚m'y9)A3-92°dONLNdÁzŒÜ˚(ÉŒ    Cap Recor;İdONLNdz¸Ü).d Str8°dONLNdızÜ()ucturΩ‡°dONLNd˙z(Ü,)eáİdONLNd˝zAÜS)3-94°dONLNdáŒì‚(êŒCap ∫¿°dONLNdá‚ì)
  11931. AttributesπİdONLNdá#ì5)A3-95°dONLNd˚(ùŒ
  11932. Join Recor•İdONLNd!î˚†)-d Str¢°dONLNd&î†')uctur'‡°dONLNd+î(†,)eÒİdONLNd.î@†R)3-95°dONLNd3°Œ≠‚(™ŒJoin $¿°dONLNd8°‚≠)
  11933. Attributes#İdONLNdD°#≠5)A3-96°dONLNdIÆŒ∫(∑Œ
  11934. Dash RecorÓ°dONLNdSÆ∫)2d StrÍİdONLNdXÆ∫,)ucturp`°dONLNd]Æ-∫1)e:°dONLNd`ÆF∫X)3-97ˇ@ˇ ˇˇˇˇ@
  11935. ˇ·ˇ‚7^
  11936. 4⁄*ˇ¯, Palatino
  11937. .(·*vi,     Helvetica
  11938. +rDraft. PreliminaryVP):, Confi)
  11939. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/20/934^*¿¯
  11940. °dONLNd\∞h…(e∞Dash m@°dONLNd\…hı)
  11941. Attributesl°dONLNd\
  11942. h)A3-98°dONLNdi∞uÎ(r∞
  11943. Pattern Recor>`°dONLNd#iÏu)<d Str:‡°dONLNd(iu)uctur¿¿°dONLNd-iu)eä`°dONLNd0i1uC)3-99°dONLNd5v∞Ç“(∞Pattern Ω†°dONLNd=v“Dz)"
  11944. Attributesº`°dONLNdIvÇ*)A3-100°dONLNdOɶè—(å¶    FunctionsİdONLNdZÉÊè˝)@3-101°dONLNd`ê∞ú (ô∞Getting and Setting Style ·`°dONLNdzê úL)p
  11945. Attributes‡ °dONLNdÜêaúx)A3-102°dONLNdåù∞©4(¶∞Getting and Setting Curve Err–İdONLNd©ù4©=)Ñor8†°dONLNd≠ùR©i)3-107°dONLNd≥™∞∂5(≥∞Getting and Setting the Pen WÒ‡°dONLNd–™5∂G)Öidth    ¿°dONLNd÷™\∂i)'3-1—°dONLNdŸ™h∂r) 12°dONLNd‹∑∞√v(¿∞+Getting and Setting Start Caps and End CapsU‡°dONLNd    ∑ã√ò)€3-1 °dONLNd ∑ò√¢)
  11946. 16°dONLNdƒ∞–(Õ∞Getting and Setting Joinsº†°dONLNd*ƒ2–I)Ç3-121°dONLNd0—∞›((⁄∞Getting and Setting DashesŒ¿°dONLNdL—<›S)å3-126°dONLNdRfi∞Í,(Á∞Getting and Setting PatternsUİdONLNdpfiAÍX)ë3-132°dONLNdvÎú˜(ÙúSummary of Geometric StylesE¿°dONLNdìÎ4˜K)ò3-140°dONLNdô¯∞(∞Constants and Data TUİdONLNd≠¯#)_ypesÌ`°dONLNd≥¯7N)(3-140°dONLNdπ∞(∞-Functions for Manipulating Geometric Style Prã¿°dONLNdÊ¢)œopertiesÒ°dONLNd∂Õ)73-142
  11947. A*H¯4B*H¯ C*C¯
  11948. ˇ·ˇ‚7^
  11949. °dONLNdˆ5*@Z(=*    Chapter 4
  11950. °dONLNd2úA$)rGeometric Operations
  11951. f`°dONLNd49@F)ù4-1°dONLNdHúT(QúAbout Geometric Operations‚@°dONLNd7H0T=)î4-3°dONLNd;U¶a(^¶Contours and Contour Dir≥¿°dONLNdSUa5)uection_@°dONLNd[UJaW)/4-4°dONLNd_b¶nl(k¶)Reducing and Simplifying Shape Geometries:`°dONLNdäbÅné)€4-8°dONLNdéo¶{Z(x¶&The Primitive Form of Shape Geometries
  11952. ¿°dONLNd∂oo{Å)…4-10°dONLNdª|¶à (Ö¶Geometric Information=°dONLNd“| à2)z4-14°dONLNd◊â¶ï(í¶Intersection and Inclusion°dONLNdÛâ-ï?)á4-16°dONLNd¯ñ¶¢÷(ü¶
  11953. Geometric ≠ °dONLNdñ÷¢)0
  11954. Arithmeticõ¿°dONLNdñ¢,)D4-19°dONLNd£úØ(¨úUsing Geometric Operations!İdONLNd/£/ØA)ì4-21°dONLNd4∞¶ºY(π¶%Determining and Reversing Contour Dir£`°dONLNdY∞Yºs)≥ectionN‡°dONLNda∞àºö)/4-21°dONLNdfΩ¶…∞(Δ¶Br`¿°dONLNdhΩ∞…)
  11955. eaking Shape Contours+¿°dONLNdΩ+…=){4-25°dONLNdÑ ¶÷c(”¶(Eliminating Unnecessary Geometric Points2İdONLNdÆ x÷ä)“4-27°dONLNd≥◊¶„˚(‡¶Simplifying Shapes¿°dONLNd«◊„")j4-29°dONLNdɶN(̶$Converting a Shape to Primitive FormÁ@°dONLNdÚ‰bt)º4-34°dONLNd˜Ò¶˝3(˙¶Finding Geometric Information å °dONLNdÒ3˝s)ç
  11956. About a Shapev‡°dONLNd$Òà˝ö)U4-36°dONLNd)˛¶
  11957. L(¶$Setting a Shape’s Bounding RectangleC@°dONLNdO˛a
  11958. s)ª4-42°dONLNdT ¶Ó(¶Insetting Shapes°dONLNdf )]4-45°dONLNdk¶$(!¶Determining Whether TҰdONLNdÄ$G)i wo Shapes Tû°dONLNdãF$[)7ouch\@°dONLNdëp$Ç)*4-47°dONLNdñ%¶1f(.¶'Determining Whether One Shape Contains SİdONLNdΩ%f1ä)¿Another1†°dONLNdΔ%ü1±)94-51°dONLNdÀ2¶> (;¶Performing Geometric À‡°dONLNd‡2 >G)e Arithmetic W≠‡°dONLNdÏ2G>t)<
  11959. ith ShapesC‡°dONLNd¯2â>õ)B4-53°dONLNd˝?úK(HúGeometric Operations Refer.İdONLNd?K+)|ence`°dONLNd?@KR)(4-60°dONLNd"L¶X(U¶Constants and Data TUİdONLNd6LX)_ypesÌ`°dONLNd<L-X?)(4-60°dONLNdAY∞eÊ(b∞ Contour Dirz °dONLNdLYÊe)6ectionsb†°dONLNdUYe+)34-60°dONLNdZf¶r—(o¶    FunctionsİdONLNdefÊr¯)@4-60°dONLNdjs∞c(|∞%Determining and Reversing Contour Dir£`°dONLNdèsc})≥ectionN‡°dONLNdósí§)/4-61°dONLNdúÄ∞å∫(â∞Br`¿°dONLNdûÄ∫å )
  11960. eaking Shape Contours+¿°dONLNdµÄ5åG){4-64°dONLNd∫ç∞ôE(ñ∞Reducing and Simplifying ShapesUİdONLNd€çZôl)™4-65°dONLNd‡ö∞¶£(£∞5Incorporating Style Information Into Shape GeometriesY°dONLNdö∏¶ (£∏4-69°dONLNdß∞≥=(∞∞Finding Geometric Information å °dONLNd:ß=≥z)ç About Shapes3‡°dONLNdHßè≥°)R4-71°dONLNdM¥∞¿G(Ω∞ Getting and Setting Shape Bounds‡°dONLNdo¥\¿n)¨4-76ˇ‘@ˇ ˇˇˇˇ@
  11961. ˇ·ˇ‚7^
  11962. 4⁄∫˙, Palatino
  11963. .I (‡
  11964. vii,     Helvetica
  11965. (Ô∫Draft. PreliminaryVP):, Confi)
  11966. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/20/934^H¿
  11967. °dONLNd\Œh(eŒInsetting Shapes°dONLNd\+h=)]4-79°dONLNdiŒu7(rŒDetermining Whether TҰdONLNd,i7uG)iwo p°dONLNd/iGuR)Ar¸@°dONLNd1iRuà)
  11968. eas Intersectj†°dONLNd@iùuØ)K4-80°dONLNdEvŒÇé(Œ'Determining Whether One Shape Contains SİdONLNdlvéÇ≤)¿Another1†°dONLNduv«ÇŸ)94-83°dONLNdzÉŒè3(åŒPerforming Geometric À‡°dONLNdèÉ3èõ)eArithmetic with Shapes'İdONLNdßÉ∞è¬)}4-87°dONLNd¨ê∫úU(ô∫Summary of Geometric Operationsé`°dONLNdÕêiú{)Ø4-98°dONLNd“ùŒ©-(¶ŒConstants and Data TUİdONLNdÊù-©A)_ypesÌ`°dONLNdÏùU©g)(4-98°dONLNdÒ™Œ∂˘(≥Œ    FunctionsİdONLNd¸™∂ )@4-98
  11969. ÊHÌ4ÁHÌ ËHË
  11970. ˇ·ˇ‚7^
  11971. °dONLNd⁄HÂx(‚H    Chapter 5
  11972. °dONLNd ◊∫Ê)r
  11973. Bitmap Shapes
  11974. j¿°dONLNdŸ-Â:)s5-1°dONLNdÌ∫˘(ˆ∫About Bitmap Shapesƒ`°dONLNd4Ì.˘;)t5-3°dONLNd8˙ƒ(ƒBitmap GeometriesæÄ°dONLNdK˙-:)i5-4°dONLNdOƒ)(ƒBitmap Styles and Inks°dONLNdg>K)z5-7°dONLNdkƒ Ï(ƒBitmap TW`°dONLNdsÏ )(    ransforms%`°dONLNd~- :)A5-8°dONLNdÇ!ƒ-(*ƒ
  11975. Bitmaps and Vr@°dONLNdè!-:)A iew DevicesᆰdONLNdú!N-`)I5-10°dONLNd°.∫:(7∫Using Bitmap Shapes†°dONLNd∂.-:?)s5-13°dONLNdª;ƒGœ(DƒCr\°dONLNdΩ;œGN) eating and Drawing Bitmaps«`°dONLNdŸ;bGt)ì5-13°dONLNdfiHŒTŸ(QŒCr\°dONLNd‡HŸTh) eating Black-and-White Bitmapsh†°dONLNdH|Té)£5-14°dONLNdUŒaŸ(^ŒCr\°dONLNdUŸa6) eating Color BitmapsÁİdONLNdUJa\)q5-19°dONLNd"bƒn[(kƒ Dithering and Halftoning Bitmapse°dONLNdDbpnÇ)¨5-28°dONLNdIoƒ{˜(xƒ
  11976. Applying TΔ†°dONLNdSoˆ{g)2ransfer Modes to Bitmapsv`°dONLNdmo|{é)Ü5-30°dONLNdr|ƒà(ÖƒConverting Other T≤@°dONLNdÑ|àç)Vypes of Shapes to Bitmaps>‡°dONLNdü|¢à¥)à5-32°dONLNd§âƒï˜(íƒ
  11977. Applying TΔ†°dONLNdÆâˆïk)2ransformations to Bitmaps¿°dONLNd…âÄïí)ä5-35°dONLNdŒñƒ¢œ(üƒCr\°dONLNd–ñœ¢) eating Bitmaps W}‡°dONLNd‡ñ¢ò)Nith Disk-Based Pixel Images톰dONLNd˝ñ¨¢æ)è5-40°dONLNd£ƒØœ(¨ƒCr\°dONLNd£œØ) eating Bitmaps Of †°dONLNd£Ø.)Pfscr“¿°dONLNd£.Ø=)een7`°dONLNd£RØd)$5-42°dONLNd#∞ƒº3(πƒEditing Parts of a Bitmapå¿°dONLNd>∞GºY)É5-49°dONLNdCΩ∫…l(Δ∫%Applying Functions Described ElsewherP@°dONLNdhΩm…¡)≥e to Bitmap Shapesà@°dONLNd|Ω’…Á)h5-51°dONLNdÅ ƒ÷,(”ƒFunctions That Post Err凰dONLNdò ,÷R)hors or WØ °dONLNd† Q÷ë)%
  11978. arnings When °dONLNd≠ í÷Ê)AApplied to Bitmap °dONLNdø◊ÿ„˜(‡ÿShapesô‡°dONLNd«◊ „)35-51°dONLNdɃ4(̃Shape-Related Functions `†°dONLNd‰‰4≥)pApplicable to Bitmap Shapes °dONLNd‰»⁄)î5-53°dONLNdÒƒ˝((˙ƒGeometric Operations v°dONLNdÒ(˝ß)dApplicable to Bitmap Shapes*İdONLNd8Òº˝Œ)î5-54°dONLNd=˛ƒ
  11979. /(ƒStyle-Related Functions G°dONLNdU˛/
  11980. Æ)kApplicable to Bitmap Shapes˚İdONLNdr˛¬
  11981. ‘)ì5-55°dONLNdw ƒ&(ƒInk-Related and Color∑ °dONLNdå &{)b-Related Functions ∫‡°dONLNdü {€)UApplicable to Bitmap °dONLNd¥ÿ$˜(!ÿShapesô‡°dONLNdº $)35-55°dONLNd¡%ƒ1 (.ƒT∫¿°dONLNd¬%…1F)ransform-Related Functions OİdONLNd›%G1Δ)~Applicable to Bitmap Shapes°dONLNd˙%€1Ì)î5-55°dONLNdˇ2ƒ>À(;ƒV+İdONLNd2À>h)"iew-Related Functions That Can Be ∫İdONLNd"2h>€)ùApplied to Bitmap Shapes™Ä°dONLNd<2>)à5-57°dONLNdA?∫K(H∫Bitmap Shapes Refer†°dONLNdT?K))\enceÂİdONLNdZ?=KO)'5-58°dONLNd_LƒX·(UƒData T:`°dONLNdeL·Xı)ypes“@°dONLNdkL    X)(5-58°dONLNdpYŒe?(bŒThe Bitmap Geometry Str{ °dONLNdáY?eV)quctur°dONLNdåYWe[)e †°dONLNdèYoeÅ)5-58°dONLNdîfŒr4(oŒThe Long Rectangle StrK°dONLNd™f5rL)guctur–‡°dONLNdØfLrP)eöİdONLNd≤ferw)5-60°dONLNd∑sŒ>(|ŒConstants For Bitmaps WÚ@°dONLNdŒs>π)pith Disk-Based Pixel Images°dONLNdÎsŒ‡)ê5-60°dONLNdÄŒå(âŒBitmap Data Sour†°dONLNdÄå()Oce y °dONLNdÄ(åM)     Alias Str.‡°dONLNd ÄNåe)&uctur¥¿°dONLNdÄeåi)e~`°dONLNdÄ~åê)5-61°dONLNdçƒôÔ(ñƒ    FunctionsİdONLNd$çô)@5-61°dONLNd)öŒ¶Ÿ(£ŒCr\°dONLNd+öŸ¶) eating BitmapsäİdONLNd;ö/¶A)V5-62°dONLNd@ߌ≥{(∞Œ%Getting and Setting Bitmap Geometries;°dONLNdgßê≥¢)¬5-64°dONLNdl¥Œ¿(ΩŒEditing Bitmaps¿°dONLNd}¥*¿<)\5-67ˇ2@ˇ ˇˇˇˇ@
  11982. ˇ·ˇ‚7^
  11983. 4⁄*ˇ¯, Palatino
  11984. .(·*viii,     Helvetica
  11985. +rDraft. PreliminaryVP):, Confi)
  11986. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/20/934^*¿¯
  11987. °dONLNd\∞h˛(e∞Drawing Bitmaps©`°dONLNd\h$)b5-72°dONLNdi∞u(r∞Checking Bitmap Colors∞‡°dONLNd.i0uB)Ä5-74°dONLNd3vúÇ(úSummary of Bitmap ShapespİdONLNdMv+Ç=)è5-76°dONLNdRÉ∞èÕ(å∞Data T:`°dONLNdXÉÕè·)ypes“@°dONLNd^Éıè)(5-76°dONLNdcê∞ú€(ô∞    FunctionsİdONLNdnêú)@5-77
  11988. Ã*”¯4Õ*”¯ Œ*Œ¯
  11989. ˇ·ˇ‚7^
  11990. °dONLNds¿*ÀZ(»*    Chapter 6
  11991. °dONLNd}ΩúÃ˙)rPicture Shapes
  11992. j¿°dONLNdçøÀ)s6-1°dONLNdí”úfl’(‹ú About Pictur~†°dONLNdû”’fl˚)9e Shapes‚ °dONLNd®”fl):6-3°dONLNd¨‡¶Ï*(ȶOverriding Styles, Inks, and T" °dONLNd ‡*ÏV)Ñ    ransforms °dONLNd’‡jÏw)@6-7°dONLNdŸÌ¶˘Ê(ˆ¶Multiple Referù¿°dONLNdÁÌÊ˘˛)@ences؆°dONLNdÓÌ˘),6-9°dONLNdÚ˙¶‰(¶
  11993. Unique Items à°dONLNdˇ˙‰ )>    AttributeI¿°dONLNd
  11994. ˙!3)=6-13°dONLNd¶¿(¶Pictur¿°dONLNd¿‰)e Hierarı`°dONLNd‰˙)$chies&°dONLNd$!)+6-14°dONLNd)¶ ¨(¶T∫¿°dONLNd*´ )ransform Concatenationˇ°dONLNdB* <)6-15°dONLNdG!¶-Ω(*¶Hit-TÖ¿°dONLNdL!Ω-Ù)
  11995. esting Pictur`°dONLNdY!ı-)8e Shapesk‡°dONLNdc!/-A):6-20°dONLNdh.ú:”(7ú Using PicturΩ‡°dONLNdt.”:˘)7e Shapes!`°dONLNd~.: );6-22°dONLNdÉ;¶G±(D¶Cr\°dONLNdÖ;±G&) eating and Drawing PicturfiİdONLNdû;&GL)ue ShapesB°dONLNd®;aGs);6-22°dONLNd≠H¶T(Q¶Getting and Setting Picturm@°dONLNd«HTR)s e GeometriesX¿°dONLNd’HgTy)N6-26°dONLNd⁄U¶a(^¶Adding Items to a Picturk¿°dONLNdÚUa)me5`°dONLNdıU,a>)6-28°dONLNd˙b¶n`(k¶(Removing and Replacing Items in a Picturfi†°dONLNd"b`nd)∫e®@°dONLNd%bynã)6-31°dONLNd*o¶{*(x¶Overriding Styles, Inks, and T" °dONLNdHo*{V)Ñ    ransforms °dONLNdSoj{|)@6-33°dONLNdX|¶à (Ö¶Adding Multiple Refere`°dONLNdm| à#)eencesw@°dONLNdt|7àI),6-35°dONLNdyâ¶ï(í¶Adding Unique Items.°dONLNdéâï-)u6-37°dONLNdìñ¶¢±(ü¶Cr\°dONLNdïñ±¢È)
  11996. eating Pictur°†°dONLNd¢ñÈ¢
  11997. )8e Hierar¶@°dONLNd™ñ
  11998. ¢#)$chies÷‡°dONLNd±ñ7¢I)*6-39°dONLNd∂£¶ØΩ(¨¶Hit-TÖ¿°dONLNdª£ΩØÙ)
  11999. esting Pictur`°dONLNd»£ıØ˛)8es°dONLNdãØ$)6-40°dONLNd—∞úºN(πú%Applying Functions Described ElsewherP@°dONLNdˆ∞Oº|)≥ e to PicturBİdONLNd∞|º¢)-e Shapes¶°dONLNd ∞∂º»):6-46°dONLNdΩ¶…(Δ¶Functions That Post Err凰dONLNd'Ω…4)hors or WØ °dONLNd/Ω3…T)%arnings˘°dONLNd8Ωh…z)56-46°dONLNd= ¶÷(”¶Shape-Related Functions?°dONLNdV (÷:)Ç6-47°dONLNd[◊¶„(‡¶Geometric OperationsT`°dONLNdq◊„.)v6-48°dONLNdv‰¶(̶Style-Related Functions%`°dONLNdè‰#5)}6-49°dONLNdîÒ¶˝Ê(˙¶Ink- and Color/`°dONLNd¢ÒÁ˝9)A-Related FunctionsİdONLNd∂ÒN˝`)g6-49°dONLNdª˛¶
  12000. ¨(¶T∫¿°dONLNdº˛´
  12001. Ù)ransform- and V8@°dONLNdÀ˛Ù
  12002. V)Iiew-Related Functions#`°dONLNd‚˛k
  12003. })w6-49°dONLNdÁ ú∂(úPictur¿°dONLNdÌ ∂ˆ)e Shapes Refer.`°dONLNd˚ ˜
  12004. )Aence@°dONLNd 1)(6-50°dONLNd¶$—(!¶    FunctionsİdONLNdÊ$¯)@6-50°dONLNd%∞1ª(.∞Cr\°dONLNd%ª1Û)
  12005. eating Pictur°†°dONLNd%%Û1)8e Shapes °dONLNd/%.1@);6-50°dONLNd42∞>#(;∞Getting and Setting Picturm@°dONLNdN2#>\)s e GeometriesX¿°dONLNd\2q>É)N6-52°dONLNda?∞KÌ(H∞Editing Pictur‡°dONLNdo?ÓK )>e Parts· °dONLNdx?K1)16-55°dONLNd}L∞XÙ(U∞Drawing Pictur¿Ä°dONLNdãLÙX˝)Des« °dONLNdèLX#)6-59°dONLNdîY∞e«(b∞Hit-TÖ¿°dONLNdôY«e˛)
  12006. esting Pictur`°dONLNd¶Yˇe)8es°dONLNd™Ye.)6-61°dONLNdØfúrÔ(oúSummary of Pictur*¿°dONLNd¿fr)Te Shapesé@°dONLNd f*r<):6-64°dONLNdœs∞Õ(|∞Data T:`°dONLNd’sÕ·)ypes“@°dONLNd€sı)(6-64°dONLNd‡Ä∞å€(â∞    FunctionsİdONLNdÎÄå)@6-64ˇ*@ˇ ˇˇˇˇ@
  12007. ˇ·ˇ‚7^
  12008. 4⁄∫˙, Palatino
  12009. ., (‡ix,     Helvetica
  12010. (Ô∫Draft. PreliminaryVP):, Confi)
  12011. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/20/934^H¿
  12012. kHr4lHr mHm
  12013. ˇ·ˇ‚7^
  12014. °dONLNd\∫kÒ(g∫Glossary
  12015. ∏İdONLNd
  12016. ^j)KGL-1
  12017. °H®4¢H® £H£
  12018. ˇ·ˇ‚7^
  12019. °dONLNdí∫°‹(ù∫Index
  12020. º‡°dONLNdî†)6IN-1ˇ@ˇ ˇˇˇˇ@
  12021. ˇ·ˇ‚7^
  12022. 4⁄*ˇ¯, Palatino
  12023. .(·*x,     Helvetica
  12024. +rDraft. PreliminaryVP):, Confi)
  12025. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/20/934^*¿¯ˇ.@ˇ ˇˇˇˇ@
  12026. ˇ·ˇ‚7^
  12027. 4⁄∫˙, Palatino
  12028. ., (‡xi,     Helvetica
  12029. (Ô∫Draft. PreliminaryVP):, Confi)
  12030. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/15/934^H¿
  12031. ˇˇ—Úˇ◊°dONLNd[∫o‰(j∫Figur{z°dONLNd[‰o)*es, T5°dONLNd
  12032. [oñ)"ables, and Listings
  12033. ®HÆ4©HÆ ™∫™
  12034. ˇ·ˇ‚7^
  12035. °dONLNdúH®s(•H    Chapter 1
  12036. °dONLNd(ù∫®;)rIntroduction to QuickDraw  °dONLNdBù<®z)Ç GX Graphics
  12037.     @°dONLNdOùç®ö)Q1-1°dONLNdT±∫º‰(π∫
  12038. Figure 1-1°dONLNd_±ºb)NShape object structureÜ0°dONLNdw±tºÅ)l1-4°dONLNd{Ω∫»·(≈∫    Table 1-1°dONLNdÖΩ»3)N
  12039. Where to fi°dONLNdêΩ4»÷),'nd information on shape-type conversionä¿°dONLNdπΩË»ı)¥1-5°dONLNdΩ…∫‘‰(—∫
  12040. Figure 1-2°dONLNd»…‘)N:The geometric shape types and examples of geometric shape °dONLNd”fi4*
  12041.  
  12042. geometries‡°dONLNd”GfiT)?1-7°dONLNdfl∫͉(Á∫
  12043. Figure 1-3°dONLNdflÍ)NA0°dONLNdflÍ)> polygon shape with a single polygon contour containing three °dONLNd\ÈÙJ(Ògeometric pointsǰdONLNdnÈ\Ùi)T1-8°dONLNdrı∫‰(˝∫
  12044. Figure 1-4°dONLNd}ıl)NFraming shapes versus fip°dONLNdïımú)e lling shapesÖ`°dONLNd£ıƪ)A1-9°dONLNdß∫ ‰(    ∫
  12045. Figure 1-5°dONLNd≤ 
  12046. )NTÄ–°dONLNd≥
  12047.  Æ)%wo condensed views of a polygon shape0°dONLNd⁄¡ ”)¥1-10°dONLNdfl
  12048. ∫‰(∫
  12049. Figure 1-6°dONLNdÍ
  12050. Ù)N:The geometric style properties and some examples of their °dONLNd$"*
  12051. ef◊‡°dONLNd&"")fectsÿ°dONLNd-4"A)%1-1.–°dONLNd0A"F)
  12052. 1°dONLNd2#∫.‰(+∫
  12053. Figure 1-7°dONLNd=#.)N>An example of eliminating unnecessary geometric points from a °dONLNd{-8 *
  12054. shape@°dONLNdÇ-38E)+1-12°dONLNdá9∫D‰(A∫
  12055. Figure 1-8°dONLNdí9Dê)N!An example of simplifying a shape°dONLNdµ9£Dµ)õ1-12°dONLNd∫E∫P‰(M∫
  12056. Figure 1-9°dONLNd≈EP)N=Some examples of the geometric information available about a °dONLNdOZ *
  12057. shape@°dONLNd    O3ZE)+1-13°dONLNd[∫fÍ(c∫ Figure 1-10°dONLNd[f
  12058. )N?Some examples of the geometric arithmetic you can perform with °dONLNdYep%*
  12059. shapesÉ@°dONLNdae7pI)/1-14°dONLNdfq∫|Í(y∫ Figure 1-11°dONLNdrq|c)NSample bitmap shapes@°dONLNdàqv|à)n1-15°dONLNdç}∫àÍ(Ö∫ Figure 1-12°dONLNdô}à)NA0°dONLNdö}àI) bitmap shape `°dONLNd™}[àm)M1-16°dONLNdØâ∫îÍ(ë∫ Figure 1-13°dONLNdªâîÑ)NElements of a bitmap geometry‡°dONLNd⁄âóî©)è1-17°dONLNdflï∫†Í(ù∫ Figure 1-14°dONLNdÎï†c)NSample picture shapes@°dONLNdïv†à)n1-18°dONLNd°∫¨Í(©∫ Figure 1-15°dONLNd°¨)NA0°dONLNd°¨F) picture shapeÜ@°dONLNd$°X¨j)J1-18°dONLNd)≠∫∏Í(µ∫ Figure 1-16°dONLNd5≠∏)NA0°dONLNd6≠∏S) picture hierarchy°dONLNdJ≠e∏w)W1-19
  12060. ‹H‚4›H‚ fi∫fi
  12061. ˇ·ˇ‚7^
  12062. °dONLNdO–H‹s(ŸH    Chapter 2
  12063. °dONLNdY—∫‹)rGeometric Shapes
  12064.     ô`°dONLNdk—'‹4)m2-1°dONLNdpÂ∫‰(Ì∫
  12065. Figure 2-1°dONLNd{Â)NA0°dONLNd|ÂC)
  12066.  shape objectáê°dONLNdãÂUb)G2-6°dONLNdèÒ∫¸‰(˘∫
  12067. Figure 2-2°dONLNdöÒ¸)N:The geometric shape types and examples of geometric shape °dONLNd‘˚4*
  12068.  
  12069. geometries‡°dONLNd‡˚GT)?2-8°dONLNd‰∫‰(∫
  12070. Figure 2-3°dONLNdÔ)NA0°dONLNd)@ polygon shape with a single contour containing three geometric °dONLNd0 (pointsҰdONLNd82?)*2-9°dONLNd<∫(‰(%∫
  12071. Figure 2-4°dONLNdG(l)NFraming shapes versus fip°dONLNd_m(ú)e lling shapesÖ`°dONLNdmÆ(ª)A2-1€@°dONLNdp∫(ø) 1°dONLNdr)∫4‰(1∫
  12072. Figure 2-5°dONLNd})4Y)NThe various shape fiÖ°dONLNdë)Y4‹)Q!lls and some examples of their ef·°dONLNd≤)‹4Ô)Éfects‚°dONLNdπ)4)%2-12°dONLNdæ5∫@‰(=∫
  12073. Figure 2-6°dONLNd…5@‚)N4The even-odd rule and winding-number rule algorithms‡°dONLNdˇ5ı@)Ì2-13°dONLNdA∫L‰(I∫
  12074. Figure 2-7°dONLNdAL
  12075. )NTÄ–°dONLNdA
  12076. L-)wo linesP°dONLNdA@LR)32-16°dONLNdM∫X‰(U∫
  12077. Figure 2-8°dONLNd*MX)NA0°dONLNd+MXj) quadratic Bézier curvep°dONLNdDM|Xé)n2-17°dONLNdIY∫d‰(a∫
  12078. Figure 2-9°dONLNdTYdÉ)NFinding the midpoint of a curveÜ`°dONLNduYïdß)ç2-18°dONLNdze∫pÍ(m∫ Figure 2-10°dONLNdÜep¶)N(Dividing a curve into two smaller curvesÄ–°dONLNd∞e∏p )∞2-18°dONLNdµq∫|Í(y∫ Figure 2-11°dONLNd¡q|)NA0°dONLNd¬q|±)& rectangle geometry shown framed and fi
  12079. °dONLNdÈq±|ø)£lled
  12080. @°dONLNdÔq—|„) 2-19°dONLNdÙ}∫àÍ(Ö∫ Figure 2-12°dONLNd}à)NA0°dONLNd}àµ)( polygon shape with two polygon contours–°dONLNd+}«àŸ)π2-21°dONLNd0â∫îÍ(ë∫ Figure 2-13°dONLNd<âî)NA0°dONLNd=âîÈ)4 polygon drawn with the even-odd and winding shape fi‡°dONLNdrâÈîÒ)€llsëİdONLNdwâî)2-22°dONLNd|ï∫†Í(ù∫ Figure 2-14°dONLNdàï†)NA0°dONLNdâï†7)
  12081.  polygon fi–°dONLNdîï7†≥))!lled with the inverseFill shape fiâ°dONLNd∂ï≥†∂)|llᆰdONLNd∫ï…†€)2-22°dONLNdø°∫¨Í(©∫ Figure 2-15°dONLNdÀ°¨)NA0°dONLNdð¨Å) path with two consecutive of‡ê°dONLNdȰĨ∂)rf-curve points·∞°dONLNd˘°»¨⁄)H2-24ˇÊ@ˇ ˇˇˇˇ@
  12082. ˇ·ˇ‚7^
  12083. 4⁄*ˇ¯, Palatino
  12084. .(·*xii,     Helvetica
  12085. +rDraft. PreliminaryVP):, Confi)
  12086. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/15/934^*¿¯
  12087.     °dONLNd\úgÃ(dú Figure 2-16°dONLNd \Íg)NA0°dONLNd
  12088. \g&)
  12089.  path shape fi`°dONLNd\&g„)60lled with the evenOddFill and windingFill shape °dONLNdKfÍqÓ(nÍfi°dONLNdMfÔq˜)lls~†°dONLNdRf    q)2-24°dONLNdWrú}»(zú Listing 2-1°dONLNdcrÍ}¢)N.Drawing a point without creating a point shape @°dONLNdìrµ}«)À2-27°dONLNdò~úâÃ(Üú Figure 2-17°dONLNd§~Íâ)NA0°dONLNd•~â) point0°dONLNd≠~â*)(2-28°dONLNd≤äúï»(íú Listing 2-2.°dONLNdæäÍïg)N Creating a point shape with the ,
  12090. Courier°dONLNdfiägïô)}
  12091. GXNewPoint°dONLNdËäôïº)2     function°dONLNdÛäŒï‡)52-29.°dONLNd¯ñú°»(ûú Listing 2-3.°dONLNdñͰg)N Creating a point shape with the °dONLNd$ñg°∑)}GXNewShapeVector°dONLNd4ñ∑°π)P .°dONLNd5†Í´    (®Ífunction–°dONLNd?†´.)22-29°dONLNdD¨ú∑»(¥ú Listing 2-4.°dONLNdP¨Í∑g)N Creating a point shape with the °dONLNdp¨g∑ô)}
  12092. GXNewShape°dONLNdz¨ô∑¨)2 and °dONLNd¨¨∑fi)
  12093. GXSetPoint°dONLNdâ¨fi∑‡)2 .°dONLNdä∂Í¡(æÍ    functionsÇ–°dONLNdï∂ ¡2)62-30°dONLNdö¬úÕ»( ú Listing 2-5.°dONLNd¶¬ÍÕ)N
  12094. Using the °dONLNd∞¬ÕD)(
  12095. GXSetPoint°dONLNd∫¬DÕÀ)2# function to replace a point shape’V°dONLNd›¬ÀÕ“)ás .°dONLNdflÃÍ◊(‘Ígeometry¿°dONLNdÈÃ"◊4)82-30°dONLNdÓÿú„Ã(‡ú Figure 2-18°dONLNd˙ÿÍ„Ô)NTÄ–°dONLNd˚ÿÔ„)wo difÿ@°dONLNdÿ„b)ferent point geometries‹†°dONLNdÿt„Ü)n2-31°dONLNd‰úÔ»(Ïú Listing 2-6°dONLNd+‰ÍÔó)N,Drawing a line without creating a line shape°dONLNdY‰™Ôº)¿2-32°dONLNd^ú˚Ã(¯ú Figure 2-19°dONLNdjÍ˚)NA0°dONLNdk˚) lineÇê°dONLNdr˚$)"2-33°dONLNdw¸ú»(ú Listing 2-7.°dONLNdɸÍa)NCreating a line shape with the °dONLNd¢¸aé)w    GXNewLine°dONLNd´¸é±)-     function°dONLNd∂¸√’)52-33.°dONLNdªú»(ú Listing 2-8°dONLNd«ÍO)NDrawing two parallel lines–°dONLNd„bt)x2-34°dONLNdËúÃ(ú Figure 2-20°dONLNdÙÍ)NParallel linesÄ0°dONLNd/A)E2-35°dONLNd     ú+Ã((ú Figure 2-21°dONLNd Í+8)NNearly parallel linesˇP°dONLNd, J+\)`2-36°dONLNd1,ú7»(4ú Listing 2-9°dONLNd=,Í7V)NCreating a rectangle shapeáP°dONLNdY,h7z)~2-37°dONLNd^8úCÃ(@ú Figure 2-22°dONLNdj8ÍC)NA0°dONLNdk8C)
  12096.  rectangleÑİdONLNdw8)C;)92-37°dONLNd|DúOÕ(Lú Listing 2-10°dONLNdâDÍOY)NCreating a framed rectangle°dONLNd¶DlO~)Ç2-38°dONLNd´Pú[Ã(Xú Figure 2-23°dONLNd∑PÍ[)NA0°dONLNd∏P[6) framed rectangleê°dONLNdÀPH[Z)X2-38°dONLNd–\úgÕ(dú Listing 2-11°dONLNd›\ÍgG)NCreating a curve shapeÖp°dONLNdı\Ygk)o2-39°dONLNd˙húsÃ(pú Figure 2-24°dONLNdhÍs)NA0°dONLNdhs#)  curve shapeܰdONLNdh5sG)E2-40°dONLNdtúÕ(|ú Listing 2-12°dONLNd'tÍ\)NDrawing a triangular polygon–°dONLNdEtoÅ)Ö2-42°dONLNdJÄúãÃ(àú Figure 2-25°dONLNdVÄÍã)NA0°dONLNdWÄã:) triangular polygon°dONLNdlÄLã^)\2-42°dONLNdqåúóÃ(îú Figure 2-26°dONLNd}åÍó)NA0°dONLNd~åóö)+ triangular polygon with an inverse shape fiãİdONLNd™åöóù)™llä °dONLNdÆå∞ó¬)2-43°dONLNd≥òú£Õ(†ú Listing 2-13°dONLNd¿òÍ£})N$Creating a polygon with two contours`°dONLNdÊò꣢)¶2-44°dONLNdΧúØÃ(¨ú Figure 2-27°dONLNd˜§ÍØ)NA0°dONLNd¯§ؘ) fiP°dONLNd˚§˜Øî)'lled polygon with two separate contoursãP°dONLNd$§¶Ø∏)Ø2-44°dONLNd)∞úªÕ(∏ú Listing 2-14°dONLNd6∞ͪí)N)Creating a polygon with a crossed contourâ0°dONLNda∞§ª∂)∫2-45°dONLNdfºú«Ã(ƒú Figure 2-28°dONLNdrºÍ«)NA0°dONLNdsº«ç)& framed polygon with a crossed contour    –°dONLNdõºü«±)Ø2-45°dONLNd†»ú”Ã(–ú Figure 2-29°dONLNd¨»Í”)NA0°dONLNd≠»”˜) fiP°dONLNd∞»˜”|)!lled polygon with crossed contour    0°dONLNd”»é”†)ó2-46°dONLNdÿ‘úflÕ(‹ú Listing 2-15°dONLNd‘Ífl¶)N.Creating a polygon with an overlapping contourㇰdONLNd‘∏fl )Œ2-46°dONLNd‡úÎÃ(Ëú Figure 2-30°dONLNd&‡ÍÎ)NA0°dONLNd'‡ÎÎ)= framed polygon with an overlapping contour and closed-frame °dONLNddÍÍı    (ÚÍshape fi`°dONLNdlÍ
  12097. ı
  12098. ) ll°dONLNdpÍ ı2)2-47°dONLNduˆúÃ(˛ú Figure 2-31°dONLNdňÍ)NA0°dONLNdLj)  even-odd fi°dONLNd鈔)/-lled polygon with an overlapping contour and °dONLNdªÍ 1(Íeven-odd shape fi°dONLNdÃ2 5)Hll∞°dONLNd–H Z)2-48°dONLNd’ úÃ(ú Figure 2-32°dONLNd· Í)NA0°dONLNd‚ —)7 contour with an overlapping contour and winding shape °dONLNdÍ!Ó(Ífi°dONLNdÔ!Ú)ll˛†°dONLNd!)2-48°dONLNd$"ú-Õ(*ú Listing 2-16°dONLNd1"Í-A)NDrawing a path shape°dONLNdG"T-f)j2-50°dONLNdL.ú9Ã(6ú Figure 2-33°dONLNdX.Í9)NA0°dONLNdY.9) path‡°dONLNd`.9()&2-51°dONLNde:úEÕ(Bú Listing 2-17°dONLNdr:ÍE\)NCreating a path using only offl@°dONLNdè:\EØ)rf-curve control pointsa°dONLNdß:¬E‘)f2-52°dONLNd¨FúQÃ(Nú Figure 2-34°dONLNd∏FÍQ)NA0°dONLNdπFQ8) round path shapeäP°dONLNdÃFJQ\)Z2-53°dONLNd—Rú]Õ(Zú Listing 2-18°dONLNdfiRÍ]ä)N(Creating a path with concentric contours∞°dONLNdRù]Ø)≥2-53°dONLNd
  12099. ^úiÃ(fú Figure 2-35°dONLNd^Íi)NA0°dONLNd^i∑)1 framed path shape with two concentric clockwise °dONLNdKhÍs (pÍcontours°dONLNdUhs1)52-54°dONLNdZtúÃ(|ú Figure 2-36°dONLNdftÍ$)N
  12100. An even-odd fiÖ`°dONLNdtt$€):.lled path shape with two concentric clockwise °dONLNd¢~Íâ (ÜÍcontours°dONLNd¨~â1)52-55°dONLNd±äúïÃ(íú Figure 2-37°dONLNdΩäÍï)NA0°dONLNdæäï)
  12101.  winding-fiÇ0°dONLNd…äïœ)(.lled path shape with two concentric clockwise °dONLNd˜îÍü (úÍcontours°dONLNd    îü1)52-55°dONLNd    †ú´Ã(®ú Figure 2-38°dONLNd    †Í´)NA0°dONLNd    †´ )6 framed paths shape with an internal counterclockwise °dONLNd    I™Íµ(≤ÍcontourǰdONLNd    R™µ,)02-56ˇ 2@ˇ ˇˇˇˇ@
  12102. ˇ·ˇ‚7^
  12103. 4⁄∫˙, Palatino
  12104. .Ñ`(‡xiii,     Helvetica
  12105. (Ô∫Draft. PreliminaryVP):, Confi)
  12106. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/15/934^H¿
  12107.     °dONLNd\∫gÍ(d∫ Figure 2-39°dONLNd \g)NA0°dONLNd
  12108. \g) fiP°dONLNd\g⁄)2lled path shape with an internal counterclockwise °dONLNdBfq&(ncontourǰdONLNdKf8qJ)02-57°dONLNdPr∫}Î(z∫ Listing 2-19°dONLNd]r}8)N Creating a fi¿°dONLNdjr9}ê)1gure-eight path shapeâİdONLNdÅr¢}¥)i2-59°dONLNdÜ~∫âÍ(Ü∫ Figure 2-40°dONLNdí~â)NA0°dONLNdì~â) fiP°dONLNdñ~âl)gure-eight path shapeä°dONLNd≠~~âê)i2-59°dONLNd≤ä∫ïÍ(í∫ Figure 2-41°dONLNdæäï)N:The result of converting a path shape to a rectangle shape°dONLNd˙äï)˚2-60°dONLNdˇñ∫°Í(û∫ Figure 2-42°dONLNd ñ°Ÿ)N5The result of converting a path shape to a line shape°dONLNdBñϰ˛)‰2-60°dONLNdG¢∫≠Í(™∫ Figure 2-43°dONLNdS¢≠)NA0°dONLNdT¢≠©)& path shape converted to a point shape톰dONLNd|¢ª≠Õ)≠2-61°dONLNdÅÆ∫πÎ(∂∫ Listing 2-20°dONLNdéÆπu)NConverting a line to a curve@°dONLNd¨Æàπö)Ä2-62°dONLNd±∫∫≈Í(¬∫ Figure 2-44°dONLNdΩ∫≈)NA0°dONLNdæ∫≈Ó)8 line shape before and after conversion to a curve shapeì`°dONLNd¯∫≈)Ú2-62°dONLNd˝Δ∫—Î(Œ∫ Listing 2-21°dONLNd
  12109. Δ—å)N!Converting a rectangle to a curve0°dONLNd-Δü—±)ó2-63°dONLNd2“∫›Í(⁄∫ Figure 2-45°dONLNd>“›)NA0°dONLNd?“›Ì)8 rectangle shape before and after conversion to a curve °dONLNdw‹Á (‰shape@°dONLNd~‹3ÁE)+2-63°dONLNdÉË∫ÛÎ(∫ Listing 2-22°dONLNdêËÛΩ)N+Converting a polygon shape to a curve shapeè °dONLNdΩ˜۷)«2-64°dONLNd¬Ù∫ˇÍ(¸∫ Figure 2-46°dONLNdŒÙˇ)NA0°dONLNdœÙˇÁ)6 polygon shape before and after conversion to a curve °dONLNd˛     (shape@°dONLNd ˛3    E)+2-64°dONLNd
  12110. ∫Î(∫ Listing 2-23°dONLNd
  12111. Ã)N/Converting a rectangle shape to a polygon shapeë°dONLNdO
  12112. fi)÷2-65°dONLNdT∫!Í(∫ Figure 2-47°dONLNd`!)NA0°dONLNda!ˆ): rectangle shape before and after conversion to a polygon °dONLNdõ + ((shape@°dONLNd¢ 3+E)+2-66°dONLNdß,∫7Î(4∫ Listing 2-24°dONLNd¥,7∏)N*Converting a path shape to a polygon shape`°dONLNd‡,À7›)√2-66°dONLNdÂ8∫CÍ(@∫ Figure 2-48°dONLNdÒ8C)NA0°dONLNdÚ8C„)5 path shape before and after conversion to a polygon °dONLNd'BM (Jshape@°dONLNd.B3ME)+2-67°dONLNd3N∫YÎ(V∫ Listing 2-25°dONLNd@NY∏)N*Converting a polygon shape to a path shape`°dONLNdlNÀY›)√2-67°dONLNdqZ∫eÍ(b∫ Figure 2-49°dONLNd}Ze)NAPolygon shape with two contours before and after conversion to a °dONLNdædo4*
  12113.  
  12114. path shape°dONLNd dGoY)?2-68°dONLNdœp∫{Î(x∫ Listing 2-26°dONLNd‹p{t)NReplacing geometric points0°dONLNd¯pá{ô)2-69°dONLNd˝|∫áÍ(Ñ∫ Figure 2-50°dONLNd    |á)NA0°dONLNd
  12115. |áb) paths shape with a flâ°dONLNd |báx)Tat top –°dONLNd(|ãáù))2-70°dONLNd-à∫ìÍ(ê∫ Figure 2-51°dONLNd9àì)NA0°dONLNd:àìΩ)+ paths shape with geometric points replacedåP°dONLNdgàœì·)¡2-70°dONLNdlî∫üÎ(ú∫ Listing 2-27°dONLNdyîü∂)N*Creating a polygon shape with two contours
  12116. ¿°dONLNd•î…ü€)¡2-71°dONLNd™†∫´Í(®∫ Figure 2-52°dONLNd∂†´)NA0°dONLNd∑†´ì)  polygon shape with two contours P°dONLNdŸ†•´∑)ó2-72°dONLNdfi¨∫∑Î(¥∫ Listing 2-28°dONLNdΨ∑ï)N#Extracting part of a polygons shape䇰dONLNd¨ß∑π)ü2-73°dONLNd∏∫√Í(¿∫ Figure 2-53°dONLNd!∏√)NA0°dONLNd"∏√Â)4 polygon shape extracted from a larger polygon shape‡°dONLNdX∏˜√    )È2-74°dONLNd]ƒ∫œÎ(Ã∫ Listing 2-29°dONLNdjƒœ«)N.Replacing geometric points of a polygons shape
  12117. °dONLNdöƒ⁄œÏ)“2-74°dONLNdü–∫€Í(ÿ∫ Figure 2-54°dONLNd´–€)NA0°dONLNd¨–€Ï)8 polygon with two geometric points replaced by a single °dONLNd‰⁄ÂE(‚geometric point°dONLNdı⁄XÂj)P2-75°dONLNd˙Ê∫ÒÍ(Ó∫ Figure 2-55°dONLNdÊÒ)NA0°dONLNdÊÒK) closed-frame fiǰdONLNdÊKÒ{)= lled polygonÖ¿°dONLNd%ÊçÒü)B2-76°dONLNd*Ú∫˝Î(˙∫ Listing 2-30°dONLNd7Ú˝o)NCreating a hollow polygon†°dONLNdRÚÇ˝î)z2-76°dONLNdW˛∫    Í(∫ Figure 2-56.°dONLNdc˛    )NAp°dONLNdd˛    â) polygon shape edited with the ,
  12118. Courierp°dONLNdɲ⠠  „){gxBreakNeitherEditp°dONLNdï˛„    Í)Z flp°dONLNdò˛Í    ˆ)ag .°dONLNdõ(setÄ°dONLNd†&8)2-77°dONLNd•∫Í(∫ Figure 2-57.°dONLNd±)NAp°dONLNd≤â) polygon shape edited with the p°dONLNd—â ){
  12119. breakLeftEditp°dONLNdfi —)A flp°dONLNd·—Í)ag setp°dONLNdȸ)+2-78.°dONLNdÓ ∫+Í((∫ Figure 2-58.°dONLNd˙ +)NAp°dONLNd˚ +é)  polygons shape edited with the p°dONLNd é+‘)ÄbreakRightEditp°dONLNd) ‘+€)F flp°dONLNd, €+Á)ag .°dONLNd/*5(2setÄ°dONLNd4*&58)2-78°dONLNd96∫AÎ(>∫ Listing 2-31°dONLNdF6AΔ)N.Creating a path shape with two curved contoursã0°dONLNdv6ÿAÍ)–2-79°dONLNd{B∫MÍ(J∫ Figure 2-59°dONLNdáBM)NA0°dONLNdàBMß)% paths shape with two curved contours ¿°dONLNdØBπMÀ)´2-80°dONLNd¥N∫YÍ(V∫ Figure 2-60.°dONLNd¿NY)NAp°dONLNd¡NYl) path shape edited with p°dONLNdŸNlY≤)^GXSetPathPartsp°dONLNdÈNƒYÿ)X2-81.°dONLNdÓZ∫eÎ(b∫ Listing 2-32°dONLNd˚Ze•)N&Creating a path shape with one contourå °dONLNd    #Z∑e…)Ø2-81°dONLNd    (f∫qÍ(n∫ Figure 2-61°dONLNd    4fq)NA0°dONLNd    5fq^) path shape with a fl    °dONLNd    Jf^qt)Pat topã–°dONLNd    RfÜqò)(2-82°dONLNd    Wr∫}Í(z∫ Figure 2-62°dONLNd    cr})NA0°dONLNd    dr}©)' path shape edited to have a pointy topİdONLNd    çrª}Õ)≠2-83°dONLNd    í~∫âÍ(Ü∫ Figure 2-63°dONLNd    û~â)NA0°dONLNd    ü~â¨)' paths shape edited to have a round topìê°dONLNd    »~æâ–)∞2-84°dONLNd    Õä∫ïÎ(í∫ Listing 2-33°dONLNd    ⁄äïf)NCreating a diagonal line†°dONLNd    Ùäyïã)q2-84°dONLNd    ˘ñ∫°Í(û∫ Figure 2-64°dONLNd
  12120. ñ°)NA0°dONLNd
  12121. ñ°C) diagonal line0°dONLNd
  12122. ñU°g)G2-85°dONLNd
  12123. ¢∫≠Í(™∫ Figure 2-65°dONLNd
  12124. '¢≠>)NAn edited line¿°dONLNd
  12125. 7¢Q≠c)I2-85ˇ(@ˇ ˇˇˇˇ@
  12126. ˇ·ˇ‚7^
  12127. 4⁄*ˇ¯, Palatino
  12128. .(·*xiv,     Helvetica
  12129. +rDraft. PreliminaryVP):, Confi)
  12130. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/15/934^*¿¯
  12131.     °dONLNd\úg√(dú    Table 2-1°dONLNd
  12132. \Ígœ)N;Shape-related functions that exhibit special behavior with °dONLNdEfÍq5*
  12133. geometric shapessp°dONLNdXfHqZ)^2-87
  12134. ï*õ¯4ñ*õ¯ óúó¯
  12135. ˇ·ˇ‚7^
  12136. °dONLNd]â*ïU(í*    Chapter 3
  12137. °dONLNdgäúïÔ)rGeometric Styles
  12138.     ?°dONLNdyäï)f3-1°dONLNd~ûú©Δ(¶ú
  12139. Figure 3-1°dONLNdâûÍ©≠)N2Style object with geometric properties highlighted¿°dONLNdΩû¿©Õ)÷3-6°dONLNd¡™úµΔ(≤ú
  12140. Figure 3-2°dONLNdÙ͵;)NShared style objectsÖ°dONLNd‚™MµZ)c3-7°dONLNdÊ∂ú¡Δ(æú
  12141. Figure 3-3°dONLNdÒ∂Í¡)NA0°dONLNdÚ∂¡Ÿ)9 geometric shape and a typographic shape sharing a style °dONLNd-¿¸À    +
  12142. 3-8°dONLNd1Ãú◊Δ(‘ú
  12143. Figure 3-4°dONLNd<ÃÍ◊Ú)NEf◊–°dONLNd>ÃÚ◊å)&fects of the GXPrimitiveShape function‡¿°dONLNdfÃû◊∞)¨3-10°dONLNdkÿú„Δ(‡ú
  12144. Figure 3-5°dONLNdvÿÍ„{)N#Another example of primitive shapes–°dONLNdõÿé„õ)§3-1[∞°dONLNdûÿö„ü) 1°dONLNd†‰úÔΔ(Ïú
  12145. Figure 3-6°dONLNd´‰ÍÔs)NThe QuickDraw GX geometric penÉ@°dONLNdÀ‰ÖÔó)õ3-15°dONLNd–ú˚Δ(¯ú
  12146. Figure 3-7°dONLNd€Í˚Ù)NDifU∞°dONLNdfiı˚9) fering pen widthsYP°dONLNdÒK˚])V3-16°dONLNdˆ¸úΔ(ú
  12147. Figure 3-8°dONLNd¸ÍV)NPixels included in a hairline0°dONLNd ¸i{)3-17°dONLNd%úΔ(ú
  12148. Figure 3-9°dONLNd0Í)NA0°dONLNd1V) geometry with no hairlineÑİdONLNdMhz)x3-17°dONLNdRúÃ(ú Figure 3-10°dONLNd^Í&)N
  12149. Pen placementÑ∞°dONLNdm8J)N3-19°dONLNdr ú+Ã((ú Figure 3-11°dONLNd~ Í+Ú)NEf◊–°dONLNdÄ Ú+{)&fect of the auto-inset style attribute``°dONLNd® é+†)ú3-19°dONLNd≠,ú7Ã(4ú Figure 3-12°dONLNdπ,Í7Ú)NEf◊–°dONLNdª,Ú7“)<fect of the auto-inset style attribute for a crossed contourdİdONLNd˘,Â7˜)Û3-20°dONLNd˛8úCÃ(@ú Figure 3-13°dONLNd
  12150. 8ÍC])NEliminating crossed contoursÉİdONLNd(8oCÅ)Ö3-20°dONLNd-DúOÃ(Lú Figure 3-14°dONLNd9DÍO_)NConstraining Shapes to Grids‡°dONLNdWDrOÑ)à3-22°dONLNd\Pú[Ã(Xú Figure 3-15°dONLNdhPÍ[t)N!Caps, Joins, Dashes, and Patterns    °dONLNdãPá[ô)ù3-23°dONLNdê\úgÃ(dú Figure 3-16°dONLNdù\Íg)NA0°dONLNdû\g+)
  12151.  capped shape    ¿°dONLNd≠\=gO)M3-24°dONLNd≤húsÃ(pú Figure 3-17°dONLNdøhÍs)N
  12152. Level capsÉİdONLNdÀh's9)=3-24°dONLNd–túÃ(|ú Figure 3-18°dONLNdfitÍ?)NStandard cap shapesà¿°dONLNdÛtQc)g3-25°dONLNd¯ÄúãÃ(àú Figure 3-19°dONLNdÄÍã)NA0°dONLNdÄã%)
  12153.  joined shapeáê°dONLNdÄ7ãI)G3-26°dONLNdåúóÃ(îú Figure 3-20°dONLNd'åÍó)N Level joins °dONLNd4å'ó9)=3-26°dONLNd9òú£Ã(†ú Figure 3-21°dONLNdGòÍ£&)NStandard joins Ñ °dONLNdXò8£J)N3-27°dONLNd]§úØÃ(¨ú Figure 3-22°dONLNdi§ÍØ;)NSharp join with miterˇ∞°dONLNdħMØ_)c3-27°dONLNdÖ∞úªÃ(∏ú Figure 3-23°dONLNdí∞ͪ)NA0°dONLNdì∞ª+)
  12154.  dashed shape    ¿°dONLNd¢∞=ªO)M3-28°dONLNdߺú«Ã(ƒú Figure 3-24°dONLNd∂ºÍ«@)NScaling a dash shapeà∞°dONLNdúR«d)h3-28°dONLNd—»ú”Ã(–ú Figure 3-25°dONLNd›»Í”Ú)NEf◊–°dONLNdfl»Ú”y)$fect of the clip-dash dash attribute‡–°dONLNd»ã”ù)ô3-29°dONLNd
  12155. ‘úflÃ(‹ú Figure 3-26°dONLNd‘ÍflÚ)NEf◊–°dONLNd‘ÚflQ)fects of breaking a dash_†°dONLNd2‘dflv)r3-30°dONLNd7‡úÎÃ(Ëú Figure 3-27°dONLNdC‡ÍÎÚ)NEf◊–°dONLNdE‡ÚÎO)fects of bending a dash·¿°dONLNd^‡aÎs)o3-30°dONLNdcÏú˜Ã(Ùú Figure 3-28°dONLNdpÏ͘)NA0°dONLNdqÏ˜3) patterned shapeâİdONLNdÉÏE˜W)U3-31°dONLNdà¯úÃ(ú Figure 3-29°dONLNdî¯Í)N
  12156. Pattern gridsҰdONLNd£¯/A)E3-31°dONLNd®úÃ( ú Figure 3-30°dONLNd¥ÍÚ)NEf◊–°dONLNd∂Úá))fects of the port-align pattern attribute`0°dONLNd·ö¨)®3-32°dONLNdÊúÃ(ú Figure 3-31°dONLNdÚÍÚ)NEf◊–°dONLNdÙÚÜ)'fects of the port-map pattern attributeflp°dONLNdò™)¶3-32°dONLNd"ú'Ã($ú Figure 3-32°dONLNd.Í')NA0°dONLNd/'{)$ shape with a cap, join, and patternçp°dONLNdUç'ü)ù3-33°dONLNdZ(ú3Ã(0ú Figure 3-33°dONLNdf(Í3)NA0°dONLNdg(3r)  shape with a dash and a patternéê°dONLNdâ(Ñ3ñ)î3-34°dONLNdé4ú?Ã(<ú Figure 3-34°dONLNdö4Í?)NA0°dONLNdõ4?¶)- shape with a clipped dash and a cap and join°dONLNd 4∏? )»3-35°dONLNdœ@úK»(Hú Listing 3-1°dONLNd€@ÍK…)N:Adding style information by directly manipulating a style °dONLNdJÍU*
  12157. objectҰdONLNdJU&)*3-36°dONLNd"VúaÃ(^ú Figure 3-35°dONLNd.VÍaK)NRectangle with thick penp°dONLNdHV^ap)t3-38°dONLNdMbúm»(jú Listing 3-2°dONLNdYbÍmá)N)Manipulating style information indirectlyÇê°dONLNdÑbôm´)Ø3-38°dONLNdânúy»(vú Listing 3-3°dONLNdïnÍyÜ)N(Constraining a shape to a half-inch gridİdONLNdønôy´)Ø3-39°dONLNdƒzúÖÃ(Çú Figure 3-36°dONLNd–zÍÖ})N$Scaled, but not constrained, V shape燰dONLNdˆzèÖ°)•3-40°dONLNd˚ÜúëÃ(éú Figure 3-37°dONLNdÜÍë>)NConstrained V shapeÜê°dONLNdÜPëb)f3-41°dONLNd!íúù»(öú Listing 3-4°dONLNd-íÍùŒ)N:Creating a shape with fractional geometric point positionsâ°dONLNdií‡ùÚ)ˆ3-42°dONLNdnûú©Ã(¶ú Figure 3-38°dONLNdzûÍ©µ)N3Rotated star not constrained to device grid (magnifi    Ä°dONLNdÆû∂©‘)Ãed 200 °dONLNdµ®Í≥ (∞Ípercent)Ä¿°dONLNdø®≥/)33-42ˇ¯@ˇ ˇˇˇˇ@
  12158. ˇ·ˇ‚7^
  12159. 4⁄∫˙, Palatino
  12160. .‡(‡ xv,     Helvetica
  12161. (Ô∫Draft. PreliminaryVP):, Confi)
  12162. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/15/934^H¿
  12163.     °dONLNd\∫gÍ(d∫ Figure 3-39°dONLNd \gƒ)N/Rotated star constrained to device grid (magnifi†°dONLNd<\≈g„)Ωed 200 °dONLNdCfq)(npercent)Ä¿°dONLNdMf;qM)33-43°dONLNdRr∫}Ê(z∫ Listing 3-5°dONLNd^r}Ü)N Converting a circle to a polygonÜ0°dONLNdÄrò}™)ê3-44°dONLNdÖ~∫âÍ(Ü∫ Figure 3-40°dONLNdë~â±)N*Accurate polygon approximation of a circle∞°dONLNdΩ~ƒâ÷)º3-44°dONLNd¬ä∫ïÍ(í∫ Figure 3-41°dONLNdŒäïΔ)N/Less accurate polygon approximation of a circleâİdONLNdˇäÿïÍ)–3-45°dONLNdñ∫°Í(û∫ Figure 3-42°dONLNdñ°”)N3Highly inaccurate polygon approximation of a circleáê°dONLNdEñ°˜)›3-45°dONLNdJ¢∫≠Í(™∫ Figure 3-43°dONLNdV¢≠®)N)Polygon resulting from a curve error of 0¿°dONLNdÅ¢ª≠Õ)≥3-46°dONLNdÜÆ∫πÊ(∂∫ Listing 3-6°dONLNdíÆπÑ)NCreating a complicated contourp°dONLNd≤Æóπ©)è3-46°dONLNd∑∫∫≈Í(¬∫ Figure 3-44°dONLNd√∫≈)NW©∞°dONLNdƒ∫≈.)avy line*‡°dONLNdŒ∫A≈S)13-47°dONLNd”Δ∫—Í(Œ∫ Figure 3-45°dONLNdflΔ—)NW©∞°dONLNd‡Δ—‘)/avy line somewhat smoothed by curve error of 101`°dONLNdΔÁ—˘)◊3-48°dONLNd“∫›Í(⁄∫ Figure 3-46°dONLNd"“›)NW©∞°dONLNd#“›©)&avy line smoothed by curve error of 15؇°dONLNdK“ª›Õ)´3-48°dONLNdPfi∫ÈÍ(Ê∫ Figure 3-47°dONLNd\fiÈ)NW©∞°dONLNd]fiȇ)5avy line completely straightened by curve error of 201¿°dONLNdîfiÛÈ)„3-48°dONLNdôÍ∫ıÊ(Ú∫ Listing 3-7°dONLNd•Íı)NDefiÄ °dONLNd©Íı7)ning a fi°dONLNd≤Í8ı`) 
  12164. gure eight°dONLNdæÍrıÑ):3-49°dONLNd√ˆ∫Í(˛∫ Figure 3-48°dONLNdœˆ)NA0°dONLNd–ˆ4)  hairline fiÇP°dONLNd‹ˆ4\)&
  12165. gure eightÖp°dONLNdˈnÄ):3-49°dONLNdÌ∫
  12166. Í(
  12167. ∫ Figure 3-49°dONLNd˘
  12168. )NA0°dONLNd˙
  12169. *) thick fi∞°dONLNd*
  12170. R)
  12171. gure eight–°dONLNdd
  12172. v):3-50°dONLNd∫Í(∫ Figure 3-50°dONLNd )NA0°dONLNd!) fiP°dONLNd$Ö)gure eight with the pen insetä¿°dONLNdCó©)Ç3-50°dONLNdH∫%Í("∫ Figure 3-51°dONLNdT%)NA0°dONLNdU%) fiP°dONLNdX%~)gure eight with path outset䆰dONLNduê%¢){3-51°dONLNdz&∫1Í(.∫ Figure 3-52°dONLNdÜ&1)NA0°dONLNdá&1:)  reversed fiɰdONLNdì&:1£),gure eight with path outset `°dONLNd∞&∂1»)|3-52°dONLNdµ2∫=Ê(:∫ Listing 3-8°dONLNd¡2=£)N#Removing unwanted contour crossingsá¿°dONLNdÊ2µ=«)≠3-52°dONLNdÎ>∫IÍ(F∫ Figure 3-53°dONLNd˜>I:)N Uncrossed fiÅ`°dONLNd>:I°)2gure eight with pen outsetâê°dONLNd>≥I≈)y3-53°dONLNd$J∫UÊ(R∫ Listing 3-9°dONLNd0JUO)NCreating an arrow‡°dONLNdCJbUt)Z3-54°dONLNdHV∫aÍ(^∫ Figure 3-54°dONLNdTVa,)NAn arrow°dONLNd^V>aP)63-56°dONLNdcb∫mÎ(j∫ Listing 3-10°dONLNdpbmò)N!Adding round caps and square capsçİdONLNdìb™mº)¢3-57°dONLNdòn∫yÍ(v∫ Figure 3-55°dONLNd§nyg)NRound and square caps°dONLNdªnzyå)r3-58°dONLNd¿z∫ÖÎ(Ç∫ Listing 3-11°dONLNdÕzÖe)NAdding joins to a shape    °dONLNdÊzxÖä)p3-58°dONLNdÎÜ∫ëÍ(é∫ Figure 3-56°dONLNd˜Üë)NA0°dONLNd¯Üëô)! square with diamond-shaped joins    @°dONLNdÜ´ëΩ)ù3-60°dONLNd í∫ùÍ(ö∫ Figure 3-57°dONLNd,íù2)N Level joins °dONLNd9íEùW)=3-60°dONLNd>û∫©Î(¶∫ Listing 3-12°dONLNdKû©ü)N%Adding a sharp join to an angle shapeé¿°dONLNdrû±©√)©3-61°dONLNdw™∫µÍ(≤∫ Figure 3-58°dONLNdÉ™µ)NV0°dONLNdÑ™µD)ery sharp joinP°dONLNdî™Vµh)H3-62°dONLNdô∂∫¡Í(æ∫ Figure 3-59°dONLNd•∂¡)NA0°dONLNd¶∂¡_) truncated sharp joinÜ°dONLNdΩ∂q¡É)c3-62°dONLNd¬¬∫ÕÎ( ∫ Listing 3-13°dONLNdœ¬Õ¡)N+Creating a curve shape dashed with diamondsãİdONLNd¸¬”ÕÂ)À3-63°dONLNdŒ∫ŸÍ(÷∫ Figure 3-60°dONLNd
  12173. ŒŸ?)N Dashed curve°dONLNdŒRŸd)J3-65°dONLNd ⁄∫ÂÍ(‚∫ Figure 3-61°dONLNd,⁄ÂE)N Scaled dashes°dONLNd<⁄XÂj)P3-65°dONLNdAÊ∫ÒÍ(Ó∫ Figure 3-62°dONLNdMÊÒF)NClipped dashesÑê°dONLNd]ÊXÒj)P3-66°dONLNdbÚ∫˝Í(˙∫ Figure 3-63°dONLNdnÚ˝F)N
  12174. Phased dashesá`°dONLNd}ÚX˝j)P3-66°dONLNdDz∫    Î(∫ Listing 3-14°dONLNdè˛    h)NCreating a dashes circle@°dONLNd©˛{    ç)s3-67°dONLNdÆ
  12175. ∫Í(∫ Figure 3-64°dONLNd∫
  12176. {)NCircle dashed with diamondsÉİdONLNd◊
  12177. çü)Ö3-68°dONLNd‹∫!Í(∫ Figure 3-65°dONLNdË!Ü)NAutomatically advanced dashes    @°dONLNdô!´)ë3-69°dONLNd "∫-Í(*∫ Figure 3-66°dONLNd"-ã)N Circle with diamond dashes inset‡°dONLNd:"û-∞)ñ3-70°dONLNd?.∫9Í(6∫ Figure 3-67°dONLNdK.9€)N2Circle with diamond dashes moved toward the center‡°dONLNd.Ó9)Ê3-71°dONLNdÑ:∫EÍ(B∫ Figure 3-68°dONLNdê:EÄ)NDash shape with two contoursÜê°dONLNdÆ:íE§)ä3-71°dONLNd≥F∫QÎ(N∫ Listing 3-15°dONLNd¿FQ†)N&Creating a dash with multiple contours`°dONLNdËF≥Q≈)´3-72°dONLNdÌR∫]Í(Z∫ Figure 3-69°dONLNd˘R]ò)N"Circle dashed with double diamonds°dONLNdR´]Ω)£3-73°dONLNd"^∫iÍ(f∫ Figure 3-70°dONLNd.^io)NCircle with dashes brokenÇê°dONLNdI^Åiì)y3-73°dONLNdNj∫uÍ(r∫ Figure 3-71°dONLNdZjuk)NCircle with airline dashesˇ∞°dONLNdvj}uè)u3-74°dONLNd{v∫ÅÍ(~∫ Figure 3-72°dONLNdávÅÑ)N Circle with bent hairline dashes0°dONLNd©vóÅ©)è3-75°dONLNdÆÇ∫çÎ(ä∫ Listing 3-16°dONLNdªÇç)NW’ê°dONLNdºÇç?) rapping textÿ–°dONLNd ÇQçc)A3-75°dONLNdœé∫ôÍ(ñ∫ Figure 3-73°dONLNd€éô)NW’ê°dONLNd‹éô=) rapped textŸÄ°dONLNdÈéOôa)?3-76°dONLNdÓö∫•Î(¢∫ Listing 3-17°dONLNd˚ö•á)N Creating a circle with 12 dashes∞°dONLNd    öö•¨)í3-77°dONLNd    "¶∫±Í(Æ∫ Figure 3-74°dONLNd    .¶±n)NDash positions for a clock°dONLNd    J¶Å±ì)y3-78°dONLNd    O≤∫ΩÎ(∫∫ Listing 3-18°dONLNd    \≤Ωc)NCreating a clock shape@°dONLNd    t≤vΩà)n3-79ˇå@ˇ ˇˇˇˇ@
  12178. ˇ·ˇ‚7^
  12179. 4⁄*ˇ¯, Palatino
  12180. .(·*xvi,     Helvetica
  12181. +rDraft. PreliminaryVP):, Confi)
  12182. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/15/934^*¿¯
  12183.     °dONLNd\úgÃ(dú Figure 3-75°dONLNd \Íg)NA0°dONLNd
  12184. \g")  clock shape–°dONLNd\4gF)D3-80°dONLNd húsÕ(pú Listing 3-19°dONLNd-hÍs5)NPatterning a shape`°dONLNdAhHsZ)^3-81°dONLNdFtúÃ(|ú Figure 3-76°dONLNdRtÍ)NA0°dONLNdSt@) patterned rectanglep°dONLNditRd)b3-82°dONLNdnÄúãÃ(àú Figure 3-77°dONLNdzÄÍãT)NPatterning a framed shapeáp°dONLNdïÄfãx)|3-83°dONLNdöåúóÕ(îú Listing 3-20°dONLNdßåÍóØ)N/Changing a pattern throughout a patterned shapeì¿°dONLNdÿå¡ó”)◊3-83°dONLNd›òú£Ã(†ú Figure 3-78°dONLNdÈòÍ£\)NShape with changing patternäP°dONLNdòn£Ä)Ñ3-85°dONLNd §úØÕ(¨ú Listing 3-21°dONLNd§ÍØs)N"Combining a cap, join, and patternà‡°dONLNd<§ÖØó)õ3-86°dONLNdA∞úªÃ(∏ú Figure 3-79°dONLNdM∞ͪÖ)N'Angle shape with cap, join, and patternå–°dONLNdv∞óª©)≠3-88°dONLNd{ºú«Ã(ƒú Figure 3-80°dONLNdáºÍ«∑)N2Shape with dash and pattern; caps and join ignoredí °dONLNdªº…«€)fl3-89°dONLNd¿»ú”Ã(–ú Figure 3-81.°dONLNdû͔x)N$Shape with cap, join, dash, and the ,
  12185. Courier°dONLNd»x”™)é
  12186. gxClipDash°dONLNd˙»™”Ê)2 dash attribute .°dONLNd
  12187. “Í›ˆ(⁄ÍsetÄ°dONLNd“›)3-90
  12188. *¯4*¯ ú¯
  12189. ˇ·ˇ‚7^
  12190. °dONLNdı*U(˛*    Chapter 4
  12191. °dONLNdˆú)rGeometric Operations
  12192.     `°dONLNd4ˆ')~4-1°dONLNd9
  12193. úΔ(ú
  12194. Figure 4-1°dONLNdD
  12195. Í )N
  12196. Line contoursÉ°dONLNdS
  12197. 2?)H4-4°dONLNdWú!Δ(ú
  12198. Figure 4-2°dONLNdbÍ!)NA0°dONLNdc!g) path shape with two contours
  12199. İdONLNdÇy!Ü)â4-5°dONLNdÜ"ú-Δ(*ú
  12200. Figure 4-3°dONLNdë"Í-)NA0°dONLNdí"-g) path shape with two contours
  12201. İdONLNd±"y-Ü)â4-5°dONLNdµ.ú9Δ(6ú
  12202. Figure 4-4°dONLNd¿.Í9)NA0°dONLNd¡.9—)8 path whose contour direction is not immediately obviousåê°dONLNd˚.„9)Û4-6°dONLNdˇ:úEΔ(Bú
  12203. Figure 4-5°dONLNd
  12204. :ÍE)NA0°dONLNd :EÔ)@ path whose inner contour has the same contour direction as its °dONLNdKDÍO(LÍ
  12205. outer contourÉp°dONLNdZD1O>)G4-7°dONLNd^Pú[Δ(Xú
  12206. Figure 4-6°dONLNdiPÍ[)NA0°dONLNdjP[¡)3 path shape whose inner and outer contours have difj∞°dONLNdùP¡[⁄)—ferent °dONLNd§ZÍe,(bÍcontour direction‡°dONLNd∑Z?eL)U4-7°dONLNdªfúqΔ(nú
  12207. Figure 4-7°dONLNdΔfÍqÚ)NEf◊–°dONLNd»fÚqº)2fects of reducing and simplifying shape geometries·∞°dONLNd¸fŒq€)‹4-9°dONLNdrú}Δ(zú
  12208. Figure 4-8°dONLNd rÍ}‰)N=How simplifying a shape can produce more predictable results °dONLNdH|Íá!*
  12209. when drawingp°dONLNdV|4áF)J4-10°dONLNd[àúìΔ(êú
  12210. Figure 4-9.°dONLNdfàÍìD)NSimple example of the °dONLNd|àDìî)ZGXPrimitiveShape°dONLNdåàîì∑)P     function°dONLNdóà…ì÷)54-1’ê°dONLNdöà’ì⁄) 1.°dONLNdúîúüÃ(úú Figure 4-10.°dONLNd®îÍüa)NMore involved example of the °dONLNd≈îaü±)wGXPrimitiveShape°dONLNd’î±ü≥)P .°dONLNd÷ûÍ©    (¶Ífunction–°dONLNd‡û©.)24-13°dONLNd™úµÃ(≤ú Figure 4-11°dONLNdҙ͵∏)N2Geometric information available about a path shapeåp°dONLNd%™ µ‹)‡4-15°dONLNd*∂ú¡Ã(æú Figure 4-12°dONLNd6∂Í¡)NA0°dONLNd7∂¡Ã)6 path shape resized by changing its bounding rectangle°dONLNdo∂fi¡)Ó4-16°dONLNdt¬úÕÃ( ú Figure 4-13°dONLNdĬÍÕÔ)NT°dONLNdŬÔÕd)esting shapes for intersection¿°dONLNd°¬vÕà)á4-17°dONLNd¶ŒúŸÃ(÷ú Figure 4-14°dONLNd≤ŒÍŸÔ)NT°dONLNd≥ŒÔŸõ))esting whether one shape contains another °dONLNdfiŒ≠Ÿø)æ4-18°dONLNd„⁄úÂÃ(‚ú Figure 4-15°dONLNdÔ⁄ÍÂf)NGeometric arithmetic with two fi~`°dONLNd⁄gÂî)} lled shapes°dONLNd⁄ßÂπ)@4-19°dONLNd!ÊúÒÃ(Óú Figure 4-16°dONLNd-ÊÍÒ∞)N0Geometric arithmetic with a framed shape and a fi‡°dONLNd^ʱҡ)«lled °dONLNdcÍ˚(¯Íshape@°dONLNdj˚')+4-20°dONLNdo¸úÃ(ú Figure 4-17°dONLNd{¸Í:)NGeometric inversionİdONLNdê¸L^)b4-20°dONLNdïú»(ú Listing 4-1°dONLNd°Í‹)N;Creating a polygon shape with two contours having opposite °dONLNd‹Í1*
  12211. contour directionsLJ°dONLNdCU)Y4-22°dONLNdıú)Ã(&ú Figure 4-18°dONLNdÍ))NA0°dONLNd)‹)8 polygon shape whose two contours have opposite contour °dONLNd:(Í3(0Í directionsrˇ`°dONLNdG(%37);4-23°dONLNdL4ú?Ã(<ú Figure 4-19°dONLNdX4Í?)NA0°dONLNdY4?∏)3 polygon shape with the direction of both contours °dONLNdå>ÍI
  12212. (FÍreversedưdONLNdñ>I1)54-24°dONLNdõJúUÃ(Rú Figure 4-20°dONLNdßJÍU)NA0°dONLNd®JU≈)7 polygon shape with the direction of the inner contour °dONLNdflTÍ_
  12213. (\ÍreversedưdONLNdÈT_1)54-24°dONLNdÓ`úk»(hú Listing 4-2°dONLNd˙`Íkó)N+Creating a path shape with a single contourã∞°dONLNd'`©kª)ø4-25°dONLNd,lúwÃ(tú Figure 4-21°dONLNd8lÍw)NA0°dONLNd9lws)! path shape with a single contourå@°dONLNd\lÖwó)ï4-26°dONLNdaxúÉÃ(Äú Figure 4-22°dONLNdmxÍÉ)NA0°dONLNdnxÉÉ)$ path shape broken into two contoursé°dONLNdîxïÉß)•4-26°dONLNdôÑúè»(åú Listing 4-3°dONLNd•ÑÍè∑)N2Creating a polygon with redundant geometric points †°dONLNdŸÑ è‹)‡4-27°dONLNdfiêúõÃ(òú Figure 4-23°dONLNdÍêÍõ)NA0°dONLNdÎêõπ)0 polygon shape with unnecessary geometric points醰dONLNd    êÀõ›)€4-28°dONLNd    "úúßÃ(§ú Figure 4-24°dONLNd    .úÍß)NA0°dONLNd    /úß…)4 poygon shape with the unnecessary geometric points °dONLNd    c¶Í±
  12214. (ÆÍremovedưdONLNd    l¶±1)54-29°dONLNd    q≤úΩ»(∫ú Listing 4-4°dONLNd    }≤ÍΩ≠)N/Creating a polygon shape with a crossed contouråê°dONLNd    Æ≤øΩ—)’4-30ˇ0@ˇ ˇˇˇˇ@
  12215. ˇ·ˇ‚7^
  12216. 4⁄∫˙, Palatino
  12217. .I (‡xvii,     Helvetica
  12218. (Ô∫Draft. PreliminaryVP):, Confi)
  12219. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/15/934^H¿
  12220.     °dONLNd\∫gÍ(d∫ Figure 4-25°dONLNd \g)NA0°dONLNd
  12221. \gß)% polygon shape with a crossed contourç °dONLNd4\πgÀ)´4-30°dONLNd9h∫sÍ(p∫ Figure 4-26°dONLNdEhs)NA0°dONLNdFhs±)' polygon shape with no crossed contours
  12222. °dONLNdoh√s’)µ4-31°dONLNdtt∫Ê(|∫ Listing 4-5°dONLNdÄt∂)N+Creating a path with two clockwise contours@°dONLNd≠t…€)¡4-31°dONLNd≤Ä∫ãÍ(à∫ Figure 4-27°dONLNdæÄã)NA0°dONLNdøÄãŸ)2 path shape with two concentric clockwise contoursã∞°dONLNdÛÄÎã˝)›4-32°dONLNd¯å∫óÍ(î∫ Figure 4-28°dONLNdåó)NA0°dONLNdåó
  12223. )? path shape with two concentric contours with opposite contour °dONLNdDñ°*(û    directionÄ∞°dONLNdOñ<°N)44-32°dONLNdT¢∫≠Í(™∫ Figure 4-29°dONLNd`¢≠)NA0°dONLNda¢≠    )> path shape with two concentric clockwise contours drawn with °dONLNdü¨∑H(¥winding shape fi∞°dONLNdبI∑L)AllP°dONLNd≥¨_∑q)4-33°dONLNd∏∏∫√Í(¿∫ Figure 4-30°dONLNdƒ∏√)NA0°dONLNd≈∏√[) path shape simplifi–°dONLNdŸ∏[√⁄)M ed to a single clockwise contour İdONLNd˚∏Ï√˛)ë4-33°dONLNdƒ∫œÊ(Ã∫ Listing 4-6°dONLNd ƒœ‡)N5Creating an hourglass polygon shape with a thick pen °dONLNdAŒŸ*
  12224. widthÄ`°dONLNdHŒ/ŸA)'4-34°dONLNdM⁄∫ÂÍ(‚∫ Figure 4-31°dONLNdY⁄Â)NA0°dONLNdZ⁄Â≈)- hourglass-shaped polygon with a thick borderå`°dONLNdâ⁄◊ÂÈ)…4-35°dONLNdéÊ∫ÒÍ(Ó∫ Figure 4-32°dONLNdöÊÒ)NA0°dONLNdõÊÒı)< polygon shape with style information incorporated into its °dONLNd◊˚-(¯geometry¿°dONLNd·@˚R)84-35°dONLNdʸ∫Í(∫ Figure 4-33°dONLNdÚ¸ÿ)N5The primitive form of the polygon shape after simplifi∞°dONLNd(¸ŸÒ)—cationê°dONLNd0¸)*4-36°dONLNd5∫Ê(∫ Listing 4-7°dONLNdA
  12225. )N?Creating a pathshape with two contours having opposite contour °dONLNdÄ.*
  12226.  
  12227. directions∞°dONLNdåAS)94-37°dONLNdë∫)Í(&∫ Figure 4-34°dONLNdù))NA0°dONLNdû)ÿ)3 path with an outer clockwise contour and an inner °dONLNd—(3m(0counterclockwise contourÉ–°dONLNdÎ(3ë)w4-37°dONLNd4∫?Í(<∫ Figure 4-35°dONLNd¸4?)NA0°dONLNd˝4?*) specifi@°dONLNd4*?í)ed point on a path contourép°dONLNd!4§?∂)z4-38°dONLNd&@∫KÍ(H∫ Figure 4-36°dONLNd2@KÁ)N8Finding the bounding rectangle and the centerpoint of a °dONLNdjJU*
  12228. pathê°dONLNdpJ,U>)$4-39°dONLNduV∫aÍ(^∫ Figure 4-37°dONLNdÅVa•)N(Finding the center point of two contours
  12229.  °dONLNd´V∏a )∞4-40°dONLNd∞b∫mÍ(j∫ Figure 4-38°dONLNdºbmu)NFinding the area of a shape    ¿°dONLNdŸbàmö)Ä4-40°dONLNdfin∫yÍ(v∫ Figure 4-39°dONLNdÍny…)N0The sum of all the contour areas of a path shape†°dONLNdn‹yÓ)‘4-41°dONLNd!z∫ÖÍ(Ç∫ Figure 4-40°dONLNd-zÖ)NA0°dONLNd.zÖ+) simplifiˇ¿°dONLNd7z+ÖI)ed path°dONLNd@z\Ön)14-42°dONLNdEÜ∫ëÊ(é∫ Listing 4-8°dONLNdQÜëe)NCreating a circular pathǰdONLNdkÜwëâ)o4-42°dONLNdpí∫ùÍ(ö∫ Figure 4-41°dONLNd|íù)NA0°dONLNd}íùA) circular pathdž°dONLNdçíSùe)E4-43°dONLNdíû∫©Í(¶∫ Figure 4-42°dONLNdûû©)NA0°dONLNdüû©`) smaller circular path`°dONLNd∑ûs©Ö)e4-44°dONLNdº™∫µÍ(≤∫ Figure 4-43°dONLNd»™µ)NA0°dONLNd…™µ§)$ path shape with a transform mappingâ°dONLNdÔ™∂µ»)®4-45°dONLNdÙ∂∫¡Ê(æ∫ Listing 4-9°dONLNd∂¡x)NCreating a tight curve shape¿°dONLNd∂ã¡ù)É4-45°dONLNd#¬∫ÕÍ( ∫ Figure 4-44°dONLNd/¬Õ)NA0°dONLNd0¬Õ:)  tight curve°dONLNd>¬LÕ^)>4-46°dONLNdCŒ∫ŸÍ(÷∫ Figure 4-45°dONLNdOŒŸ¬)N.An inset curve shape  with 16 geometric pointsäP°dONLNdŒ‘ŸÊ)Ã4-46°dONLNdÑ⁄∫ÂÍ(‚∫ Figure 4-46°dONLNdê⁄ÂF)NAn outset curve–°dONLNd°⁄YÂk)Q4-47°dONLNd¶Ê∫ÒÎ(Ó∫ Listing 4-10°dONLNd≥ÊÒ¿)N.Creating a rectangle and a circular path shape @°dONLNd„Ê”ÒÂ)À4-48°dONLNdËÚ∫˝Í(˙∫ Figure 4-47°dONLNdÙÚ˝)NA0°dONLNdıÚ˝ú)% rectangle containing a circular path    †°dONLNdÚÆ˝¿)†4-48°dONLNd!˛∫    Í(∫ Figure 4-48°dONLNd-˛    )NA0°dONLNd.˛    ø)- rectangle that touches a circular path shape¿°dONLNd]˛—    „)√4-49°dONLNdb
  12230. ∫Í(∫ Figure 4-49°dONLNdn
  12231. )NA0°dONLNdo
  12232. Ë)9 rectangle and a circular path touching at a single point@°dONLNd™
  12233. ˙ )Ï4-50°dONLNdØ∫!Í(∫ Figure 4-50°dONLNdª!)NA0°dONLNdº!Ù)< large circular path shape touching a smaller circular path °dONLNd¯ + ((shape@°dONLNdˇ 3+E)+4-51°dONLNd,∫7Î(4∫ Listing 4-11°dONLNd,7∑)N*Creating a donut-shaped path and a smallerç@°dONLNd;,∑7Á)Ø
  12234. , concentric °dONLNdH6A(>pathê°dONLNdN6,A>)$4-51°dONLNdSB∫MÍ(J∫ Figure 4-51°dONLNd_BM)NA0°dONLNd`BM)A path shape with two contours and a smaller concentric rectangle °dONLNd°LW (Tshape@°dONLNd®L3WE)+4-53°dONLNd≠X∫cÎ(`∫ Listing 4-12°dONLNd∫Xc˚)N<Creating a diamond-shaped polygon and a circlular path that °dONLNdˆbm**
  12235.     intersectÄ∞°dONLNd    b<mN)44-54°dONLNd    n∫yÍ(v∫ Figure 4-52°dONLNd    ny)NA0°dONLNd    nyÏ)5 diamond-shaped polygon geometry and a circular path °dONLNd    HxÉ-(Ägeometry¿°dONLNd    Rx@ÉR)84-55°dONLNd    WÑ∫èÍ(å∫ Figure 4-53°dONLNd    cÑè¸)N<The intersection of a diamond-shaped polygon and a circular °dONLNd    üéô*
  12236. pathê°dONLNd    •é,ô>)$4-55°dONLNd    ™ö∫•Í(¢∫ Figure 4-54°dONLNd    ∂ö•‰)N5The union of a diamond-shaped polygon and a circular °dONLNd    Î§Ø*
  12237. pathê°dONLNd    Ò§,Ø>)$4-56ˇƒ@ˇ ˇˇˇˇ@
  12238. ˇ·ˇ‚7^
  12239. 4⁄*ˇ¯, Palatino
  12240. .(·*xviii,     Helvetica
  12241. +rDraft. PreliminaryVP):, Confi)
  12242. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/15/934^*¿¯
  12243.     °dONLNd\úgÃ(dú Figure 4-55°dONLNd \Íg‰)N<The union of a framed diamond-shaped polygon and a circular °dONLNdHfÍq˚*
  12244. pathê°dONLNdNfq )$4-57°dONLNdSrú}Ã(zú Figure 4-56°dONLNd_rÍ}È)N@The result of subtracting a circular path from a diamond-shaped °dONLNdü|Íá    *
  12245. polygon`°dONLNd®|á.)24-57°dONLNd≠àúìÃ(êú Figure 4-57°dONLNdπàÍì˜)NCThe result of subtracting a diamond-shaped polygon from a circular °dONLNd¸íÍù˚*
  12246. pathê°dONLNdíù )$4-58°dONLNdûú©Ã(¶ú Figure 4-58°dONLNdûÍ©◊)N<The result of the exclusive-or operation on a polygon and a °dONLNdO®Í≥˚*
  12247. pathê°dONLNdU®≥ )$4-59°dONLNdZ¥úøÃ(ºú Figure 4-59°dONLNdf¥Íø?)NAn inverted diamond Ö`°dONLNd|¥Qøc)g4-59
  12248. „*ȯ4‰*ȯ Âú¯
  12249. ˇ·ˇ‚7^
  12250. °dONLNdÅ◊*„U(‡*    Chapter 5
  12251. °dONLNdãÿú„Ê)r
  12252. Bitmap Shapes
  12253.     `°dONLNdöÿ˘„)]5-1°dONLNdüÏú˜Δ(Ùú
  12254. Figure 5-1°dONLNd™Ï͘)NA0°dONLNd´Ï˜()
  12255.  bitmap shapeÜ@°dONLNd∫Ï:˜G)J5-4°dONLNdæ¯úΔ(ú
  12256. Figure 5-2°dONLNd…¯Í)NA0°dONLNd ¯w)  black-and-white bitmap geometry°dONLNdϯâñ)ô5-6°dONLNdúΔ( ú
  12257. Figure 5-3°dONLNd˚Í)NA0°dONLNd¸^) grayscale bitmap geometryÖ °dONLNdp})Ä5-6°dONLNdúΔ(ú
  12258. Figure 5-4°dONLNd'Í)NThe efŸ°dONLNd-£)'fect of transfer modes on bitmap shapesb`°dONLNdV∂√)≥5-8°dONLNdZú'Δ($ú
  12259. Figure 5-5°dONLNdeÍ')NThe efŸ°dONLNdk'é)!fect of mappings on bitmap shapesc °dONLNdé°'Æ)û5-9°dONLNdí(ú3Δ(0ú
  12260. Figure 5-6.°dONLNdù(Í3)NThe efV°dONLNd£(3.) fect of the ,
  12261. CourierV°dONLNdØ(.3ç)+gxMapTransformShapeV°dONLNd¬(ç3⁄)_ shape attribute on .°dONLNd÷2Í=1(:Íbitmap mappings LJ°dONLNdË2C=U)Y5-10°dONLNdÌ>úIΔ(Fú
  12262. Figure 5-7°dONLNd¯>ÍIQ)NBitmaps and view devicesİdONLNd>dIv)z5-12°dONLNdJúU»(Rú Listing 5-1°dONLNd#JÍUr)N!Creating a black-and-white bitmapê°dONLNdFJÖUó)õ5-14°dONLNdKVúaΔ(^ú
  12263. Figure 5-8°dONLNdVVÍa)NA0°dONLNdWVaá)$ black-and-white bitmap—32 bits wideÜİdONLNd}Vôa´)©5-15°dONLNdÇbúmΔ(jú
  12264. Figure 5-9°dONLNdçbÍmÖ)N%An example of unaligned bytes per row    ∞°dONLNd¥bòm™)Æ5-18°dONLNdπnúy»(vú Listing 5-2°dONLNd≈nÍy)NA0°dONLNdΔnyØ)/ bit image with an even number of bytes per rowä0°dONLNd˜n¡y”)—5-18°dONLNd¸zúÖÃ(Çú Figure 5-10°dONLNdzÍÖW)NAn envelope with a shadow    0°dONLNd#zjÖ|)Ä5-19°dONLNd(ÜúëÃ(éú Figure 5-11°dONLNd4ÜÍë)NA0°dONLNd5Üë¥)1 thinner envelope bitmap with four shades of greyç–°dONLNdhÜΔëÿ)÷5-20°dONLNdmíúùÃ(öú Figure 5-12°dONLNdyíÍù)NA0°dONLNdzíù|)# bitmap with sixteen shades of grayâp°dONLNdüíéù†)û5-21°dONLNd§ûú©»(¶ú Listing 5-3°dONLNd∞ûÍ©˙)NDefiÄ °dONLNd¥û˙©7)ning a color setɆ°dONLNdΔûI©[)O5-21°dONLNdÀ™úµÃ(≤ú Figure 5-13°dONLNd◊™Íµ)NA0°dONLNdÿ™µP) bitmap with eight colorsÑP°dONLNdÛ™bµt)r5-22°dONLNd¯∂ú¡»(æú Listing 5-4°dONLNd∂Í¡@)NCreating a color rampİdONLNd∂S¡e)i5-24°dONLNd ¬úÕÃ( ú Figure 5-14°dONLNd,¬ÍÕ)NA0°dONLNd-¬Õd) color ramp from red to greenɰdONLNdL¬vÕà)Ü5-26°dONLNdQŒúŸ»(÷ú Listing 5-5°dONLNd]ŒÍŸô)N,Creating a color ramp using the ramp library °dONLNd㌨Ÿæ)¬5-26°dONLNdê⁄ú»(‚ú Listing 5-6°dONLNdú⁄ͺ)N4Creating a color ramp using both the ramp and color °dONLNd–‰ÍÔ    *
  12265.     libraries˝¿°dONLNd€‰Ô-)15-27°dONLNd‡ú˚Ã(¯ú Figure 5-15°dONLNdÏÍ˚.)NDithered bitmapsÅ`°dONLNd˛@˚R)V5-29°dONLNd¸ú»(ú Listing 5-7°dONLNd¸Í7)NHalftoning a bitmap‡°dONLNd$¸J\)`5-29°dONLNd)úÃ(ú Figure 5-16°dONLNd5Í2)NHalftoned bitmaps†°dONLNdHEW)[5-30°dONLNdMú»(ú Listing 5-8°dONLNdYÍ})N$Applying a transfer mode to a bitmapá∞°dONLNdè°)•5-30°dONLNdÑ ú+Ã((ú Figure 5-17°dONLNdê Í+)NA0°dONLNdë +?) blended color rampÖ`°dONLNd¶ Q+c)a5-31°dONLNd´,ú7»(4ú Listing 5-9°dONLNd∑,Í7`)NConverting a path to a bitmapá–°dONLNd÷,r7Ñ)à5-32°dONLNd€8úCÃ(@ú Figure 5-18°dONLNdÁ8ÍC)NA0°dONLNdË8Cä)& bitmap representation of a path shapeİdONLNd8úCÆ)¨5-33°dONLNdDúOÃ(Lú Figure 5-19°dONLNd!DÍO)NA0°dONLNd"DOy)" bitmap and its bounding rectangleåp°dONLNdFDãOù)õ5-33°dONLNdKPú[Ã(Xú Figure 5-20°dONLNdWPÍ[)NA0°dONLNdXP[u) bitmap drawn over a backgroundâP°dONLNdyPá[ô)ó5-34°dONLNd~\úgÃ(dú Figure 5-21°dONLNdä\Íg)NA0°dONLNdã\g…)4 bitmap with a transfer mode drawn over a backgroundã`°dONLNd¡\€gÌ)Î5-35°dONLNdΔhúsÃ(pú Figure 5-22°dONLNd“hÍs)NA0°dONLNd”hsï)(  path shape converted to a bitmap shapeëp°dONLNd˝hßsπ)∑5-36°dONLNdtúÃ(|ú Figure 5-23°dONLNdtÍ)NA0°dONLNdtª)1 path shape converted to a bitmap shape and then °dONLNd@~Íâ(ÜÍskewed¿°dONLNdH~â-)15-36°dONLNdMäúïÃ(íú Figure 5-24°dONLNdYäÍï)NA0°dONLNdZäï:) color ramp bitmapÅ¿°dONLNdnäLï^)\5-37°dONLNdsñú°Ã(ûú Figure 5-25°dONLNdñͰ)NA0°dONLNdÄñ°Ñ)& bitmap after multiple transformations†°dONLNd®ññ°®)¶5-37°dONLNd≠¢ú≠Õ(™ú Listing 5-10°dONLNd∫¢Í≠)N Scaling text°dONLNd»¢+≠=)A5-38°dONLNdÕÆúπÃ(∂ú Figure 5-26°dONLNdŸÆÍπ)N Scaled text∞°dONLNdÊÆ)π;)?5-38ˇ.@ˇ ˇˇˇˇ@
  12266. ˇ·ˇ‚7^
  12267. 4⁄∫˙, Palatino
  12268. ., (‡    xix,     Helvetica
  12269. (Ô∫Draft. PreliminaryVP):, Confi)
  12270. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/15/934^H¿
  12271.     °dONLNd\∫gÎ(d∫ Listing 5-11°dONLNd
  12272. \gJ)NScaling a bitmapp°dONLNd\]go)U5-38°dONLNd$h∫sÍ(p∫ Figure 5-27°dONLNd0hsá)NScaled text and a scaled bitmap    ¿°dONLNdQhös¨)í5-39°dONLNdVt∫Í(|∫ Figure 5-28°dONLNdbt)NA0°dONLNdctJ) clipped bitmapч°dONLNdtt\n)N5-40°dONLNdyÄ∫ãÎ(à∫ Listing 5-12°dONLNdÜÄã¯)N9Creating a black-and-white bitmap that uses QuickDraw GX °dONLNdøäï(*
  12273. memory˝∞°dONLNd«ä:ïL)25-43°dONLNdÃñ∫°Î(û∫ Listing 5-13°dONLNdŸñ°@)NCreating an of⁄p°dONLNdÁñ@°{)8fscreen bitmap‹`°dONLNd˜ñç°ü)M5-46°dONLNd¸¢∫≠Í(™∫ Figure 5-29°dONLNd¢≠ê)N!Multiple shapes drawn to a bitmap–°dONLNd+¢£≠µ)õ5-47°dONLNd0Æ∫πÎ(∂∫ Listing 5-14°dONLNd=Æπ@)NCreating an of⁄p°dONLNdKÆ@π¨)8fscreen bitmap using the of∏ °dONLNdfƨπ‰)lfscreen library7 °dONLNdwÆ˜π    )K5-47°dONLNd|∫∫≈Í(¬∫ Figure 5-30°dONLNdà∫≈X)NAn extracted bitmapÑê°dONLNdù∫j≈|)b5-49°dONLNd¢Δ∫—Í(Œ∫ Figure 5-31°dONLNdÆΔ—P)NAn editied bitmap ÑİdONLNd¬Δb—t)Z5-50°dONLNd«“∫›·(⁄∫    Table 5-1°dONLNd—“›ˇ)N=Geometry-related functions that post errors or warnings when °dONLNd‹ÁQ*
  12274. applied to bitmapsÑp°dONLNd"‹cÁu)[5-52°dONLNd'Ë∫Û·(∫    Table 5-2°dONLNd1ËÛ)NBGeometric operations that post errors or warnings when applied to °dONLNdsÚ˝'*
  12275. bitmapsê°dONLNd|Ú:˝L)25-52°dONLNdŞ∫    ·(∫    Table 5-3°dONLNdã˛    )NCShape-related functions that exhibit special behavior when applied °dONLNdŒ1*
  12276.  
  12277. to bitmaps†°dONLNd⁄DV)<5-53°dONLNdfl∫·(∫    Table 5-4°dONLNdÈ)NCGeometric operations that exhibit special behavior when applied to °dONLNd,)'*
  12278. bitmapsê°dONLNd5:)L)25-54°dONLNd:*∫5·(2∫    Table 5-5°dONLNdD*5
  12279. )NT™p°dONLNdE*
  12280. 5)>ransform-related functions that exhibit special behavior when °dONLNdÉ4?Q(<applied to bitmapsÑp°dONLNdó4c?u)[5-56°dONLNdú@∫K·(H∫    Table 5-6°dONLNd¶@K)NVW∞°dONLNdß@K€)4iew-related functions that can be applied to bitmapsd0°dONLNd›@ÌKˇ)fl5-57
  12281. oHu4pHu q∫q
  12282. ˇ·ˇ‚7^
  12283. °dONLNd‚cHos(lH    Chapter 6
  12284. °dONLNdÏd∫o)rPicture Shapes
  12285.     `°dONLNd¸do$)]6-1°dONLNdx∫ɉ(Ä∫
  12286. Figure 6-1°dONLNd xÉ)NA0°dONLNd
  12287. xÉF) picture shapeÜ@°dONLNdxXÉe)J6-4°dONLNd!Ñ∫è‰(å∫
  12288. Figure 6-2°dONLNd,Ñè)NA0°dONLNd-Ñè>)
  12289.  picture item°dONLNd<ÑQè^)C6-5°dONLNd@ê∫õ‰(ò∫
  12290. Figure 6-3°dONLNdKêõ)NA0°dONLNdLêõé)  picture geometry with two itemsLJ°dONLNdnê†õ≠)í6-6°dONLNdrú∫߉(§∫
  12291. Figure 6-4°dONLNd}úßé)N Condensed picture with two items–°dONLNdüú°ßÆ)ô6-7°dONLNd£®∫≥‰(∞∫
  12292. Figure 6-5°dONLNdÆ®≥)NA0°dONLNdØ®≥Ä) picture shape with overridesܰdONLNdŒ®í≥ü)Ñ6-8°dONLNd“¥∫ø‰(º∫
  12293. Figure 6-6°dONLNd›¥ø)NA0°dONLNdfi¥øÚ)9 picture containing multiple references to the same shape`°dONLNd¥ø)ˆ6-9°dONLNd¿∫À‰(»∫
  12294. Figure 6-7°dONLNd(¿À)NA0°dONLNd)¿À>)
  12295.  picture item°dONLNd8¿QÀc)C6-10°dONLNd=Ã∫◊‰(‘∫
  12296. Figure 6-8°dONLNdHÃ◊Ω)N.Multiple references with overriding transformsˇ†°dONLNdxÜ◊‹)«6-1UİdONLNd{Ë◊·)
  12297. 1°dONLNd}ÿ∫„‰(‡∫
  12298. Figure 6-9°dONLNdàÿ„ÿ)N7Multitple references with overriding styles, inks, and °dONLNdø‚Ì2*
  12299.  
  12300. transforms˛¿°dONLNdÀ‚DÌV)<6-12°dONLNd–Ó∫˘Í(ˆ∫ Figure 6-10°dONLNd‹Ó˘ÿ)N4Adding shapes to a picture without the unique items °dONLNd¯(*
  12301.     attribute†°dONLNd¯;M)36-13°dONLNd ∫Í( ∫ Figure 6-11°dONLNd,Ï)N:Adding shapes to a picture with the unique items attribute@°dONLNdhˇ)˜6-14°dONLNdm∫Í(∫ Figure 6-12°dONLNdy)NA0°dONLNdzß)& condensed view of a picture hierarchyäP°dONLNd¢πÀ)´6-15°dONLNdß∫'Í($∫ Figure 6-13°dONLNd≥')NA0°dONLNd¥'Ç) path shape and its transformâ@°dONLNd”î'¶)Ü6-16°dONLNdÿ(∫3Í(0∫ Figure 6-14°dONLNd‰(3)NA0°dONLNdÂ(3ù)% picture with an overriding transform`°dONLNd (Ø3¡)°6-17°dONLNd4∫?Í(<∫ Figure 6-15°dONLNd4?Ü)NSimple transform concatenation¿°dONLNd=4ô?´)ë6-18°dONLNdB@∫KÍ(H∫ Figure 6-16°dONLNdN@Kã)N!Intricate transform concatenationÖ‡°dONLNdq@ùKØ)ï6-19°dONLNdvL∫WÍ(T∫ Figure 6-17°dONLNdÇLW)NA0°dONLNdÉLWå)  picture shape and its transform@°dONLNd•LûW∞)ê6-21°dONLNd™X∫cÊ(`∫ Listing 6-1°dONLNd∂Xcò)N$Creating a simple picture of a houseÜ¿°dONLNd‹X™cº)¢6-23°dONLNd·d∫oÍ(l∫ Figure 6-18°dONLNdÌdo)NA0°dONLNdÓdo±)* picture of a house with a roof and a dooré0°dONLNdd√o’)µ6-25°dONLNdp∫{Ê(x∫ Listing 6-2°dONLNd+p{)NCDisposing of shapes contained in a picture before disposing of the °dONLNdnzÖ#*
  12302. pictureÄê°dONLNdwz5ÖG)-6-26°dONLNd|Ü∫ëÊ(é∫ Listing 6-3°dONLNdàÜë∞)N+Extracting and editing items from a pictureÖ@°dONLNdµÜ¬ë‘)∫6-27°dONLNd∫í∫ùÍ(ö∫ Figure 6-19°dONLNdΔíù)NA0°dONLNd«íùÆ)) picture of a house with a relocated door p°dONLNdÚí¿ù“)≤6-28°dONLNd˜û∫©Ê(¶∫ Listing 6-4°dONLNd    û©)NDefiÄ °dONLNd    û©∞)%ning new shapes for the house pictureå°dONLNd    .û¬©‘)™6-28°dONLNd    3™∫µÊ(≤∫ Listing 6-5°dONLNd    ?™µ®)N&Adding new shapes to the house pictureé¿°dONLNd    g™∫µÃ)≤6-29ˇÃ@ˇ ˇˇˇˇ@
  12303. ˇ·ˇ‚7^
  12304. 4⁄*ˇ¯, Palatino
  12305. .(·*xx,     Helvetica
  12306. +rDraft. PreliminaryVP):, Confi)
  12307. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/15/934^*¿¯
  12308.     °dONLNd\úgÃ(dú Figure 6-20°dONLNd \Íg)NA0°dONLNd
  12309. \ga) house with a lawn, walkway[°dONLNd(\`gò)p
  12310. , and chimney_0°dONLNd7\™gº)J6-30°dONLNd<hús»(pú Listing 6-6°dONLNdHhÍsl)NRemoving an item from a pictureÅp°dONLNdih~sê)î6-31°dONLNdntúÃ(|ú Figure 6-21°dONLNdztÍ)NA0°dONLNd{tg) house with chimney removedê°dONLNdòtyã)â6-31°dONLNdùÄúã»(àú Listing 6-7°dONLNd©ÄÍãr)N Replacing one shape with another䆰dONLNdÀÄÑãñ)ö6-32°dONLNd–åúóÃ(îú Figure 6-22°dONLNd‹åÍó)NA0°dONLNd›åóu)  house with the chimney replaced⇰dONLNdˇåáóô)ó6-32°dONLNdòú£»(†ú Listing 6-8°dONLNdòÍ£ç)N*Creating style, ink, and transform objectsÖ°dONLNd=òü£±)µ6-33°dONLNdB§úØ»(¨ú Listing 6-9°dONLNdN§ÍØÍ)NACreating a picture whose items have overriding styles, inks, and °dONLNdèÆÍπ*
  12311.  
  12312. transforms˛¿°dONLNdõÆ&π8)<6-34°dONLNd†∫ú≈Õ(¬ú Listing 6-10°dONLNd≠∫Í≈Â)NADisposing of overriding style, ink, and transform objects before °dONLNdӃ͜    *
  12313. drawingê°dONLNd˜ƒœ.)26-35°dONLNd¸–ú€Ã(ÿú Figure 6-23°dONLNd–Í€)NA0°dONLNd    –€”); house picture with an overriding style, ink, and transformä0°dONLNdF–€˜)ı6-35°dONLNdK‹úÁÕ(‰ú Listing 6-11°dONLNdX‹ÍÁfi)N=Adding four items to a house picture that reference the same °dONLNdïÊÍÒ*
  12314. shape@°dONLNdúÊÒ')+6-36°dONLNd°Úú˝Õ(˙ú Listing 6-12°dONLNdÆÚÍ˝Î)NADisposing of the white rectangle and the three transform objects °dONLNdÔ¸Í%*
  12315. before drawing¿°dONLNdˇ¸8J)N6-37°dONLNdúÃ(ú Figure 6-24°dONLNdÍ)NA0°dONLNdT) house with four windowsÜP°dONLNd+fx)v6-37°dONLNd0úÕ(ú Listing 6-13°dONLNd=Íj)N Adding unique items to a pictureê°dONLNd_}è)ì6-38°dONLNdd ú+Ã((ú Figure 6-25°dONLNdp Í+)NA0°dONLNdq +¬)4 house with four windows and four unique overriding °dONLNd•*Í5(2Í
  12316. transforms˛¿°dONLNd±*&58)<6-39°dONLNd∂6úAÕ(>ú Listing 6-14°dONLNdƒ6ÍAX)NCreating a picture hierarchy`°dONLNd‚6kA})Å6-39°dONLNdÁBúMÃ(Jú Figure 6-26°dONLNdÛBÍM)NA0°dONLNdÙBMç)& house rotated by 90 degrees two times凰dONLNdBüM±)Ø6-40°dONLNd!NúYÕ(Vú Listing 6-15°dONLNd.NÍYX)NCreating a picture hierarchy`°dONLNdLNkY})Å6-41°dONLNdQZúeÃ(bú Figure 6-27°dONLNd]ZÍe*)NGrounds pictureÇ¿°dONLNdnZ<eN)R6-42°dONLNdsfúqÃ(nú Figure 6-28°dONLNdfÍq!)N
  12317. House picturep°dONLNdéf4qF)J6-42°dONLNdìrú}Ã(zú Figure 6-29°dONLNdürÍ}º)N4Picture containing grounds picture and house pictureép°dONLNd’rŒ}‡)‰6-43°dONLNd⁄~úâÕ(Üú Listing 6-16°dONLNdÁ~ÍâR)NHit-testing a picture shapep°dONLNd~eâw){6-44°dONLNd    äúïÃ(íú Figure 6-30°dONLNdäÍïò)N,Hit-testing the picture of house and grounds ‡°dONLNdCä´ïΩ)¡6-44°dONLNdHñú°√(ûú    Table 6-1°dONLNdRñͰM)NHit-testing a picture at difŸp°dONLNdnñM°¨)cferent levels and depthsa@°dONLNdàñø°—)r6-44°dONLNdç¢ú≠√(™ú    Table 6-2°dONLNdó¢Í≠Ù)NBGeometric operations that post errors or warnings when applied to °dONLNdŸ¨Í∑    *
  12318. picturesê°dONLNd„¨∑.)26-46°dONLNdË∏ú√√(¿ú    Table 6-3°dONLNdÚ∏Í√Ù)NCShape-related functions that exhibit special behavior when applied °dONLNd5¬ÍÕ*
  12319. to pictures†°dONLNdB¬&Õ8)<6-48°dONLNdGŒúŸ√(÷ú    Table 6-4°dONLNdQŒÍŸı)NCGeometric operations that exhibit special behavior when applied to °dONLNdîÿÍ„    *
  12320. picturesê°dONLNdûÿ„.)26-48ˇ0@ˇ ˇˇˇˇ@
  12321. ˇ·ˇ‚7^
  12322. 4⁄∫˙, Palatino
  12323. ., (·    xxi,     Helvetica
  12324. (Ô∫Draft. PreliminaryVP):, Confi)
  12325. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/15/93
  12326.     3, Ã(#∫PREFN )3ACE 4^H¿
  12327. vHú4vHú óHó
  12328. ˇ·ˇ‚7^
  12329. ˇˇ¬òˇ◊°dONLNd\∫ui(n∫About This Book
  12330. °dONLNdú∫®ò*70QuickDraw GX is an integrated, object-based apprİdONLNdBúô®„)floach to graphics °dONLNdS©∫µ√(≤∫prG °dONLNdU©ƒµù)
  12331. -ogramming on Macintosh computers. This book, ÛİdONLNdÇ©ùµÁ)ŸInside Macintosh: °dONLNdî∂∫¬$(ø∫QuickDraw GX Graphics,¨°dONLNd™∂$¬)j3 describes the data types and functions you use to °dONLNd›√∫œ¬(Ã∫crµ@°dONLNdfl√¬œ)eate graphic images.°dONLNdÙ’∫·    (fi∫For application prı@°dONLNd’    ·∏)O"ogramming purposes, QuickDraw GX r˜¿°dONLNd(’∏·Î)Ø eplaces the °dONLNd4‚∫Ó£(Î∫4capabilities of some of the Macintosh system softwarX °dONLNdh‚£Ó)Èe managers documented °dONLNd~Ô∫˚(¯∫in other parts of º¿°dONLNdêÔ˚K)IInside Macintosh.¿°dONLNd°ÔL˚¿)I Information in this book r⇰dONLNdºÔ¿˚Û)t eplaces the °dONLNd»¸∫=(∫information in all chapters of 醰dONLNdÁ¸=µ)ÉInside Macintosh: Imaging W°dONLNd¸∂Û)y
  12332. ith QuickDrawİdONLNd¸Ûı)=.°dONLNd∫—(∫BeforÛ¿°dONLNd—Ô)e you ré °dONLNdp)ead this book, you should alrˆ†°dONLNd:p)Ä!eady be familiar withinformation °dONLNd[∫'($∫described elsewherJ@°dONLNdm'1)U    e in the +°dONLNdv2'Ø)#Inside Macintosh: QuickDraw °dONLNdíØ'Ω)}GX@°dONLNdîΩ'Û)  books befor†°dONLNd†Ù')7e you °dONLNd¶(∫4Ω(1∫rE°dONLNdß(æ45)ead this book. In particular…†°dONLNd√(446)v,,
  12333.  
  12334. Zapf Dingbats
  12335. °dONLNd≈>∫Eø(D∫n
  12336. °dONLNd«;ΔGc) %For a rivetting overview of the entirHİdONLNdÏ;dG°)û e QuickDraw „¿°dONLNd¯;°G∫)=GX aru`°dONLNd˝;ªG·)    chitectur* °dONLNd;‚G)'    e, and a °dONLNdGΔS
  12337. (PΔcompelling intr`@°dONLNdG
  12338. S?)D oduction to í`°dONLNd*G?SH)5prYİdONLNd,GISÃ)
  12339. ogramming with QuickDraw Ê`°dONLNdEGÃS)ÉGX, you should °dONLNdTSΔ_…(\ΔrE°dONLNdUS _Ò)    eadthe fr††°dONLNd^SÒ_=)'ee-spirited and fr∏°dONLNdpS=_~)Lollicking tome Ñ`°dONLNdS_…)BGetting Started WJ@°dONLNdêS _◊)Kith °dONLNdî_Δk¯(hΔ
  12340. QuickDraw Û°dONLNdû_¯k)2GXc@°dONLNd†_k    ).
  12341. °dONLNd¢t∫{ø(z∫n
  12342. °dONLNd§qΔ}Ã) Y@İdONLNd•qÃ}d)$ou should, at the very least, have r@°dONLNd…qd}Ÿ)òead the information about °dONLNd„}Δâ¸(ÜΔ
  12343. QuickDraw —†°dONLNdÌ}¸â∏)6+GX shapes and objects in the chapter  “Intr@`°dONLNd}πâÓ)Ω oduction to °dONLNd$âΔï¸(íΔ
  12344. QuickDraw —†°dONLNd.â¸ï)6GX” in ÿ°dONLNd5âïö)!Inside Macintosh: QuickDraw -°dONLNdQâõï )~
  12345. GX Objectsy¿°dONLNd[â ïœ)/. L °dONLNd]âœï’)Y †°dONLNd^â’ï)
  12346. ou should °dONLNdhïΔ°fi(ûΔalso r_‡°dONLNdnïfi°¶)-ead the chapter “Shape Objects” in that book.
  12347. °dONLNdú™∫±ø(∞∫n
  12348. °dONLNdûßΔ≥›) BeforÛ¿°dONLNd£ß›≥˚)e you ré °dONLNd™߸≥)<ead Chapter 3, “Geometric Styles,” in this book, you should °dONLNdÊ≥Δø…(ºΔrE°dONLNdÁ≥ ø`)#ead the chapter “Style Objects” in :†°dONLNd
  12349. ≥aøfi)óInside Macintosh: QuickDraw 膰dONLNd&≥fiø)} GX Objects.
  12350. 
  12351. °dONLNd2»∫œø(Œ∫n
  12352. °dONLNd4≈Δ—Ï) As you rU°dONLNd<≈Ï—)&@ead this chapter and the other chapters in this book, you might °dONLNd|—Δ›ü(⁄Δ2want to be familiar with the other information in 2†°dONLNdÆ—†›Í)⁄Inside Macintosh: °dONLNd¿›Δȯ(ÊΔ
  12353. QuickDraw Û°dONLNd ›¯È')2
  12354. GX Objects?¿°dONLNd‘›(Èh)0—in particular.°dONLNd‚›hȵ)@, you might also rx‡°dONLNdÙ›µÈÓ)M
  12355. ead the “Ink °dONLNdÈΔı(ÚΔObjects,” and “Tõ`°dONLNdÈı¿)H(ransform Objects” chapters in that book.
  12356. ˚H4¸H
  12357. &H.4'H. (H(
  12358. ˇ·ˇ‚7^
  12359. ˇˇ©ˇÆ°dONLNd;H&™(!H What to ReadˇˇˇˇˇˇV˛(!0
  12360. °dONLNdI7∫C(@∫This chapter intrõ°dONLNdZ7C1)I
  12361. oduces thr°dONLNdd72Cö)/ee types of QuickDraw  İdONLNdz7öC
  12362. )hGX shapes you can use to °dONLNdìD∫P(M∫make graphic images:
  12363. °dONLNd®Z∫aø*n
  12364. °dONLNd™WΔc) geometric shapes
  12365. °dONLNdªl∫sø(r∫n
  12366. °dONLNdΩiΔu)
  12367. bitmap shapes
  12368. °dONLNdÀ~∫Öø(Ñ∫n
  12369. °dONLNdÕ{Δá‡) picturÈ@°dONLNd”{‡á)e shapes°dONLNd‹å∫òB(ï∫The other types of QuickDraw vİdONLNd˘åCòÌ)â%GX shapes (the typographic shapes) ar≤İdONLNdåÌòÙ)™e °dONLNd ô∫•Ú(¢∫
  12370. discussed in Q†°dONLNd-ôÛ•á)9 Inside Macintosh: QuickDraw GX T«†°dONLNdMôÜ•∞)ì    ypographyp°dONLNdVô∞•≤)*.ˇ¥@ˇ ˇˇˇˇ@
  12371. ˇ·ˇ‚7^
  12372. 4⁄*˙¯, Palatino
  12373. .(·*xxii,     Helvetica
  12374. +rDraft. PreliminaryVP):, Confi)
  12375. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/15/93
  12376.     3, Ã(#úPREFN )3ACE 4^*¿¯
  12377. °dONLNd\úhˆ(eúGeometric shapes arg†°dONLNd\ˆhÎ)Z8e the building blocks for graphics. These shapes, which °dONLNdKiúu(rú include points, lines, curves, r4@°dONLNdki uÊ)Ñ,ectangles, polygons, and paths, make up the °dONLNdóvúÇr(ú-graphic elements supported by most drawing pr≈ °dONLNdƒvrÇœ)÷ograms. The chapter °dONLNdÿÉúèÂ(åúJ“Geometric Shapes” in this book describes geometric shapes in detail. The °dONLNd"êúúÔ*
  12378. Ochapter “Geometric Styles” in this book describes the stylistic variations you °dONLNdqùú©Ë*
  12379. Ican make to geometric shapes. The chapter “Geometric Operations” in this °dONLNd∫™ú∂ı*
  12380. Lbook describes the functions you can use to manipulate geometric shapes and °dONLNd∑ú√U*
  12381. (obtain geometric information about them.°dONLNd/…ú’æ*@Bitmap shapes contain pixel images. These shapes allow you to crm‡°dONLNdo…æ’“(“æeate °dONLNdt÷ú‚Ú(flúOgraphics by specifying the color value of each pixel in the image. The chapter °dONLNd√„úÔÒ*
  12382. M“Bitmap Shapes” in this book describes bitmap shapes in detail. This chapter °dONLNdú¸¥*
  12383. also r_‡°dONLNd¥¸ƒ)efer °dONLNd≈¸à),ences a number of the color plates you can fi¯‡°dONLNdGà¸∏)√ nd at the frû†°dONLNdSπ¸Ë)1 ont of this °dONLNd_˝ú    ¥(úbook.°dONLNdeú∂*Pictur¿°dONLNdk∂Ê) e shapes arñİdONLNdvÁa)1e collections of QuickDraw ö °dONLNdëa€)zGX shapes, including other °dONLNd¨ú(∂(%úpicturÈ@°dONLNd≤∂(‡)
  12384. e shapes. `°dONLNdº·(Á)+Y‹‡°dONLNdΩÊ( )ou can fi߇°dONLNdΔ (◊)&/nd this type of shape described in the chapter °dONLNdı)ú5ª(2ú“Pictur¿°dONLNd¸)ª5!)e Shapes,” in this book.
  12385. <*W¯4=*W¯
  12386. g*o¯4h*o¯ i*i˛
  12387. ˇ·ˇ‚7^
  12388. ˇˇ©ˇÆ°dONLNdT*g{(b*
  12389. Chapter Or2ѰdONLNd T|g»)R
  12390. ganizationˇˇˇˇˇˇV˛(b0
  12391. °dONLNd,xúÑ[(Åú+Most chapters in this book follow a standarv@°dONLNdWx[Ñí)ø
  12392. d general stræ¿°dONLNddxíÑ©)7ucturD†°dONLNdix™ÑÔ)e. For example, °dONLNdyÖúëÆ(éú=the chapter “Geometric Shapes” contains these major sections:,
  12393.  
  12394. Zapf Dingbats
  12395. °dONLNd∑õú¢°*n
  12396. °dONLNdπò®§j) *“About Geometric Shapes.” This sections pr∑`°dONLNd„òj§Œ)¬ovides an overview of °dONLNd˘§®∞˜(≠®geometric shapes.
  12397. °dONLNd πú¿°(øún
  12398. °dONLNd
  12399. ∂®¬…) ?“Using Geometric Shapes.” This section describes how you can cr‡°dONLNdL∂ ¬Ò(ø     eate and °dONLNdU¬®ŒÊ(À®Dmanipulate geometric shapes using QuickDraw GX. It describes how to °dONLNdôŒ®⁄W* &use the most common functions, gives rΩ@°dONLNdøŒW⁄Ï)Ø#elated user interface information, °dONLNd‚⁄®ʱ(„®prG °dONLNd‰⁄≤Ê¥)
  12400. 9ovides code samples, and supplies additional information.
  12401. °dONLNdÔúˆ°(ıún
  12402. °dONLNd Ï®¯) “Geometric Shapes ReferˇÄ°dONLNd7ϯt)nence.” This section prõİdONLNdMÏu¯À)_ovides a complete rć°dONLNd`ÏÀ¯€)Vefer-°dONLNddÏ‹¯Ú)ence °dONLNdi¯®·(®Fto geometric shapesgeometric shapes by describing the constants, data °dONLNdØ®‰* Gtypes, and functions that you use with geometric shapes. Each function °dONLNdˆ®(* description follows a standar∂İdONLNd(¬)Ä#d format, which gives the function °dONLNd6®(Ø(%®=declaration; a description of every parameter; the function r…‡°dONLNdsØ(Á(%Øesult, if any; °dONLNdÇ(®4Í(1®and a list of err‡°dONLNdì(Î4Ú)C<ors, warnings, and notices. Most function descriptions give °dONLNdœ4®@¥(=®<additional information about using the function and include °dONLNd @®L∞* crµ@°dONLNd
  12403. @∞L≈)oss-rΩ†°dONLNd@≈L’)eferi¿°dONLNd@÷Lˇ)
  12404. ences to r¯Ä°dONLNd @ˇL{))elated information elsewher˝@°dONLNd;@{LÇ)|e.
  12405. °dONLNd>Uú\°([ún
  12406. °dONLNd@R®^÷) B“Summary of Geometric Shapes.” This shows the C interface for the °dONLNdÇ^®jfi* Fconstants, data types, and functions associated with geometric shapes.
  12407. p*ã¯4q*ã¯
  12408. õ*£¯4ú*£¯ ù*ù˛
  12409. ˇ·ˇ‚7^
  12410. ˇˇ©ˇÆ°dONLNd à*õ
  12411. (ñ*Conventions Used in This BookˇˇˇˇˇˇV˛(ñ0
  12412. °dONLNdȨú∏P(µú(This book uses various conventions to prD‡°dONLNd    ¨Q∏Á)µ#esent certain types of information.ˇ¿@ˇ ˇˇˇˇ@
  12413. ˇ·ˇ‚7^
  12414. 4⁄∫˙, Palatino
  12415. .Ñ`(·xxiii,     Helvetica
  12416. (Ô∫Draft. PreliminaryVP):, Confi)
  12417. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/15/93
  12418.     3, Ã(#∫PREFN )3ACE 4^H¿
  12419. kHr4lHr m∫mF
  12420. ˇ·ˇ‚7^
  12421. ˇˇ‹.ˇ◊°dONLNd\∫k (g∫
  12422. Special Fontsˇˇˇˇˇˇ€r(g0
  12423. °dONLNdr∫~
  12424. ({∫All code listings, r~ °dONLNd#r
  12425. ~@)P eserved worfi °dONLNd.r@~æ)6ds, and the names of data str≤‡°dONLNdKrø~÷)uctur8¿°dONLNdPr◊~)es, constants, .°dONLNd_∫ã¡(à∫fi°dONLNda¡ãY)"elds, parameters, and functions arR`°dONLNdÉYãÆ)òe shown in Courier ,
  12426. CourierR`°dONLNdñÆã‰)U    (this is °dONLNdüå∫ò(ï∫    Courier)..°dONLNd©û∫™*When new terms ar3°dONLNd∫û™()We intr=¿°dONLNd¿û(™l)oduced, they ar›@°dONLNdœûl™|)De in‡†°dONLNd”û|™®)
  12427.  boldface.O°dONLNd›û©™Ï)- These terms arf°dONLNdÏûÏ™)Ce also °dONLNdÛ´∫∑ (¥∫defir °dONLNd˜´À∑ )ned in the Glossary°dONLNd
  12428. ´ ∑")U.
  12429. ‹H„4›H„ fi∫fiF
  12430. ˇ·ˇ‚7^
  12431. ˇˇ‹.ˇ◊°dONLNd Õ∫‹¬(ÿ∫T$é°dONLNd
  12432. Õ¬‹)
  12433. ypes of Notesˇˇˇˇˇˇ€r(ÿ0
  12434. °dONLNd„∫ÔŒ(Ï∫Ther¿°dONLNd „œÔfl)e ar`°dONLNd$„flÔò),e several types of notes used in this book. 
  12435. ˝H 4˛H 
  12436.     °dONLNdQ¸∫Õ(∫Note
  12437. ˇ·ˇ‚7^
  12438. °dONLNdV    ∫¡*A∫†°dONLNdW    ¡æ)< note formatted like this contains information that is interú °dONLNdì    æÏ)˝ esting but °dONLNdû∫!Ê(∫Dpossibly not essential to an understanding of the main text. The worº°dONLNd‚Ê!¸(Êding °dONLNdÁ!∫-P(*∫ in the tag may say something mor” °dONLNd!P-Á)ñ$e descriptive than just “Note,” for °dONLNd+-∫9Ì(6∫
  12439. example “T∞ °dONLNd5-Ï9?)2erminology Note.”,
  12440.  
  12441. Zapf Dingbats
  12442. º °dONLNdG0D8J)Xu
  12443. FHT4GHT°dONLNdIG∫OŸ(M∫IMPORTİdONLNdOGŸOÈ)ANT
  12444. ˇ·ˇ‚7^
  12445. °dONLNdSR∫^¡([∫A∫†°dONLNdTR¡^◊)B note like this contains information that is especially important.
  12446. û‡°dONLNdóU›]‰([›s
  12447. kHy4lHy
  12448. °dONLNdôk¶uÆ(s¶s
  12449. °dONLNdöl∫t√(r∫WúİdONLNdõl√tÓ)    ARNING
  12450. ˇ·ˇ‚7^
  12451. °dONLNd¢w∫Ƀ(Ä∫Wï°dONLNd£w√Éá)    /arnings like this indicate potential serious prF °dONLNd“wàÉÚ)≈oblems that you should °dONLNdÈÉ∫è›(å∫be awarm@°dONLNdÉ›èó)#+e of as you design your application. FailurïİdONLNdÉóè⁄)∫e to heed these °dONLNd+è∫õ(ò∫warnings could r÷‡°dONLNd;èõ¥)K)esult in system crashes and loss of data.
  12452. †°dONLNdeí∫ö¡)µs
  12453. øHΔ4¿HΔ ¡∫¡F
  12454. ˇ·ˇ‚7^
  12455. ˇˇ‹.ˇ◊°dONLNdg∞∫ø-(ª∫Numerical Formatsˇˇˇˇˇˇ€r(ª0
  12456. °dONLNdzΔ∫“)(œ∫Hexadecimal numbers ar∞`°dONLNdêΔ)“¨)oe shown in this format: 0x008.°dONLNdØÿ∫‰[(·∫$The numerical values of constants arİdONLNd”ÿ\‰)¢)e shown in decimal, unless the constants °dONLNd¸Â∫Ò¬(Ó∫arE°dONLNd˛Â√Ò–)    e flõ`°dONLNd–ÒË)
  12457. =ag or mask elements that can be summed, in which case they arã¿°dONLNd?ÂËÒ(ÓËe shown °dONLNdGÚ∫˛ˇ(˚∫in hexadecimal.
  12458. #H*4$H* %∫%F
  12459. ˇ·ˇ‚7^
  12460. ˇˇ‹.ˇ◊°dONLNdW∫#˛*$
  12461. Illustrationsˇˇˇˇˇˇ€r(0
  12462. °dONLNdf*∫6;(3∫The following conventions ar◊@°dONLNdÇ*;6”)Å%e used in illustrations in this book.°dONLNd®<∫HQ(E∫$In illustrations that show object prŸ°dONLNdÃ<QHÉ)ó operties, pr`°dONLNdÿ<ÑHΔ)3operties that arÖ¿°dONLNdË<ΔHÈ)B    e object °dONLNdÒI∫UΩ(R∫rE°dONLNdÚIæUŒ)eferÒ °dONLNdˆIŒUÒ)ences arH°dONLNd˛IÚU )$
  12463. e in italics.°dONLNd [∫gœ(d∫In orj`°dONLNd[œg)Gder to focus attention on the key part of some drawings, other parts ar–°dONLNdX[g (de °dONLNdZh∫t¸(q∫printed in gray °dONLNdih¸tN)B, rather than black.°dONLNd~z∫Üw(É∫+This book also uses other conventions for rl`°dONLNd©zwÜÖ)Ωepr˝ °dONLNd¨zÖÜ)esenting shape objects, style °dONLNd á∫ìu(ê∫-objects, ink objects, and transform objects.  °dONLNd˜ávì|)ºY√†°dONLNd¯á{ì†)ou can fi醰dONLNdá°ìÊ)&nd examples in °dONLNdî∫†“(ù∫FigurR¿°dONLNdŸ)e ú`°dONLNd)
  12464. 1-1, Figur√°dONLNd!î†
  12465. )*e  †°dONLNd#î †H)1-3, and Figur†`°dONLNd1îH†O)=e ͰdONLNd3îO†Ø)1-5 in Chapter 1, “Intrò°dONLNdJî∞†Â)a oduction to °dONLNdV°∫≠0(™∫QuickDraw GX Graphics.”ˇ‰@ˇ ˇˇˇˇ@
  12466. ˇ·ˇ‚7^
  12467. 4⁄*˙¯, Palatino
  12468. .(·*xxiv,     Helvetica
  12469. +rDraft. PreliminaryVP):, Confi)
  12470. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/15/93
  12471.     3, Ã(#úPREFN )3ACE 4^*¿¯
  12472. ^*x¯4^*x¯
  12473. à*ê¯4â*ꯠä*ä˛
  12474. ˇ·ˇ‚7^
  12475. ˇˇ©ˇÆ°dONLNdu*à∏(É*Development EnvirLr°dONLNdu∏àÔ)éonmentˇˇˇˇˇˇV˛(É0
  12476. °dONLNdôú•é(¢ú4The QuickDraw GX functions described in this book ar9İdONLNdMôè•Â)Ûe available using C °dONLNda¶ú≤›(ØúFinterfaces. How you access these functions depends on the development °dONLNdß≥úø≥*
  12477. envirn†°dONLNd¨≥≥øÛ)
  12478. onment you ar7†°dONLNdπ≥Ùø)Ae using.°dONLNd¬≈ú—(ŒúCode listings in this book arİdONLNdfl≈—J)| e shown in R¿°dONLNdÍ≈J—‚)2 ANSI C. They suggest methods of °dONLNd
  12479. “úfiı(€úOusing various functions and illustrate techniques for accomplishing particular °dONLNdYflúÎ∑*
  12480. tasks. m °dONLNd`fl∑΃)Although most code listings have been compiled and tested, †°dONLNdõflƒÎ·(˃Apple °dONLNd°Ïú¯…(ıúComputer+°dONLNd©Ï…¯„)-B, Inc., does not intend for you to use these code samples in your °dONLNd΢ú‘(ú
  12481. applications.
  12482.  *'¯4
  12483. *'¯
  12484. 7*?¯48*?¯ 9*9˛
  12485. ˇ·ˇ‚7^
  12486. ˇˇ©ˇÆ°dONLNd˙$*7â(2* Developer Pr¥(°dONLNd$â7)_oducts and SupportˇˇˇˇˇˇV˛(20
  12487. °dONLNdHúTπ(QúAPDAH¿°dONLNdHπT≈) is ¿°dONLNd"H≈T1) Apple’s worldwide sour¯ °dONLNd8H0Tn)kce for over thr¿°dONLNdGHoTñ)?ee hundrº†°dONLNdOHñT‡)'ed development °dONLNd^Uúa‰(^útools, technical rw¿°dONLNdpU‰a¸)Hesour¿°dONLNduU¸a>)ces, training prµ†°dONLNdÖU>a›)B#oducts, and information for anyone °dONLNd®bún∞(kúinter
  12488. ¿°dONLNd≠b±nP)$ested in developing applications on M`°dONLNd—bPn‘)üApple platforms. Customers rj°dONLNdÌb‘nÒ)Ñeceive °dONLNdÙoú{◊(xúthe quarterly f`°dONLNdoÿ{Ù)<APDA[@°dONLNdoÙ{¸) T€@°dONLNdo˚{.)
  12489. ools Catalog ~°dONLNdo/{y)4featuring all curr @°dONLNd'oz{Ω)Kent versions of Ù`°dONLNd7oº{Ÿ)BApple °dONLNd=|úàb(Öú+development tools and the most popular thirÈ¿°dONLNdh|bà‹)Δd-party development tools. °dONLNdÉâúïß(íúOr ‡°dONLNdÖâ®ï˚) dering is easy; therü@°dONLNdôâ˚ï )Se ar≠‡°dONLNdùâ ï›).e no membership fees, and application forms arΔ‡°dONLNdÀâ›ïı)“e not °dONLNd—ñú¢ü(üúrE°dONLNd“ñ†¢∑)equir\@°dONLNd◊ñ∑¢)ed for most of our prF@°dONLNdÏñ¢5)\oducts. o‡°dONLNdÙñ5¢R)"APDA8†°dONLNd¯ñR¢]) ofT`°dONLNd˚ñ]¢‡) fers convenient payment and °dONLNd£úØT(¨ú+shipping options, including site licensing.°dONLNdCµú¡¢*Tµ¿°dONLNdDµ°¡≤)o or¿°dONLNdHµ≤¡Õ)der pr‡°dONLNdNµŒ¡    )oducts or to rÒ‡°dONLNd\µ¡®):#equest a complimentary copy of the Ç@°dONLNdµ©¡≈)°APDAw °dONLNdɵ≈¡Õ) T˜ °dONLNdֵáfi)ools °dONLNdä¬úŒª(ÀúCatalogó`°dONLNd묪Œ‚)
  12490. , contact °dONLNdú‘ú‡π(›úAPDAH¿°dONLNd†‘π‡ª) °dONLNd¢·úÌÁ(ÍúApple Computer(İdONLNd∞·ÁÌ˛)K, Inc. °dONLNd∏Óú˙¢(˜úP?†°dONLNdπÓ°˙“) .O. Box 319°dONLNd≈˚ú´(úBuf… °dONLNd»˚´œ)falo, NYG†°dONLNd–˚–)%  14207-0319°dONLNd´ãúó¬(îú    If you pr@°dONLNd¥ã√ó)' ovide commerã °dONLNd¿ãó)?cial pr@°dONLNd«ãó’)+oducts and services, call 408-974-4897 for °dONLNdÚòú§O(°ú'information on the developer support pr  °dONLNdòP§§)¥ograms available fr‹‡°dONLNd,ò§§¥)Tom H°dONLNd/òµ§“)Apple.°dONLNd€
  12491. ú¢(úTµ¿°dONLNd‹
  12492. °…)elephone°dONLNdÂ
  12493. ˛z)]800-282-2732 (United States)°dONLNd˛$a* 800-637-0029 (Canada)°dONLNd#˛/y* 716-871-6555 (International)°dONLNd63ú?´(<úFax°dONLNd:3˛?1)b 716-871-651õ °dONLNdE31?8)31 °dONLNdICúOÀ(Lú    AppleLink°dONLNdSC˛O)bAPDA°dONLNdYSú_‚(\úAmerica Online°dONLNdhS˛_)bAPDA°dONLNdncúo’(lú
  12494. CompuServe°dONLNdyc˛o-)b
  12495. 76666,2405°dONLNdÖsúø(|úInternet°dONLNdés˛})bAPDA@applelink.apple.comˇd@ˇ ˇˇˇˇ@
  12496. ˇ·ˇ‚7^
  12497. 4⁄∫˙,     Helvetica
  12498.     .(‡∫Contents, Palatino
  12499. , (‡    1-1
  12500. (Ô∫Draft. PreliminaryVP):, Confi)
  12501. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/15/93
  12502.     3, Ã(#∫CHAPTER ÿ)h1ˇˇˇˇˇˇ(JH
  12503. Figure 1-0*     Listing 1-0*    T)able 1-0
  12504. ˇˇ∫Ρ◊(qH1°dONLNd[∫xÂ)rIntr9°dONLNd[Âxq)+ oduction to 
  12505. óHI4óHI 1H1
  12506. °dONLNd&6∫G˘(C∫Contents
  12507. ˇ·ˇ‚7^
  12508. ˇˇ∫Ρ◊°dONLNdx∫ïI(é∫
  12509. QuickDraw ~Œ°dONLNdxJï‡)ê GX Graphics
  12510. °dONLNd/X∫dG(a∫About QuickDraw GX Graphics)°dONLNdLX\di)¢1-3°dONLNdPe∫q    (n∫Geometric Shapes%`°dONLNdbeq+)d1-6°dONLNdfrƒ~({ƒGeometric Shape T£ °dONLNdwr~+)Sypes;°dONLNd}r@~M))1-6°dONLNdŃãD(àƒGeometric Shape Geometries
  12511. @°dONLNdùYãf)ï1-7°dONLNd°åƒò$(ïƒGeometric Shape Fills̆°dONLNd∏å8òE)t1-8°dONLNdºôƒ•E(¢ƒGeometric Styles, Inks, and T؆°dONLNdŸôD•p)Ä    ransforms}†°dONLNd‰ôÖ•í)A1-9°dONLNd˶ƒ≤%(؃Geometric OperationsT`°dONLNd˛¶:≤G)v1-1†°dONLNd¶G≤L)
  12512. 1°dONLNd≥∫ø˚(º∫
  12513. Bitmap Shapes6İdONLNd≥ø")V1-15°dONLNd¿∫Ñ(…∫Pictur¿°dONLNd¿‘Ã˙)e ShapesT@°dONLNd'¿Ã!);1-17ˇp@ˇ ˇˇˇˇ@
  12514. ˇ·ˇ‚7^
  12515. 4*\¯, Palatino
  12516. &e.3+ú"CHAPTER à)>14⁄*˙¯
  12517. (‡*1-2,     Helvetica
  12518.     )rContents
  12519. *Draft. PreliminaryVP):, Confi)
  12520. dential. ©∑1)1993I±) ˘Å)Apple ComputerÒ)7, Inc. Ìë)12/15/934^*¿¯ˇ.@ˇ ˇˇˇˇ@
  12521. ˇ·ˇ‚7^, Palatino
  12522. &e.3+ä"CHAPTER à)>1
  12523. 4⁄ä˙,     Helvetica
  12524.     (‡äAbout QuickDraw GX Graphics
  12525. , (‡    1-3
  12526. (ÔäDraft. PreliminaryVP):. ©bp)    1993Ù) §¿)Apple Computer¥0)6, Inc. ò–)12/15/93
  12527.     ˇˇ—˚ˇÆ°dONLNd8äCÔ(@äIntroduction to QuickDraw ÷n°dONLNd8ÔC )e GX Graphicsˇˇˇˇˇˇ≠5(@1
  12528. °dONLNd&\äh”(eäThis chapter intrõ°dONLNd7\”h)I
  12529. oduces thr°dONLNdA\hj)/ee types of QuickDraw  İdONLNdW\jh¯)hGX shapes you can use to make °dONLNduiäu–(rägraphic images:,
  12530.  
  12531. Zapf Dingbats
  12532. °dONLNdÖäÜè*n
  12533. °dONLNdá|ñà‚) geometric shapes
  12534. °dONLNdòëäòè(óän
  12535. °dONLNdöéñö÷)
  12536. bitmap shapes
  12537. °dONLNd®£ä™è(©än
  12538. °dONLNd™†ñ¨∞) picturÈ@°dONLNd∞†∞¨’)e shapes°dONLNdπ±äΩ(∫äThe other types of QuickDraw vİdONLNd÷±ΩΩ)â%GX shapes (the typographic shapes) ar≤İdONLNd˚±ΩΩ˝)™e discussed in °dONLNd
  12539. æä ((«ä Inside Macintosh: QuickDraw GX T˘ °dONLNd*æ' W)ù    ypography»Ä°dONLNd3æW Y)0.°dONLNd5–ä‹ê(ŸäY@İdONLNd6–ê‹î)9ou should be familiar with information described elsewherI‡°dONLNdo–î‹∂(Ÿî    e in the *†°dONLNdx–∑‹)#Inside Macintosh: °dONLNdä›äȺ(Êä
  12540. QuickDraw Û°dONLNdȠ)2GXc@°dONLNdñ›ÀÈ)  books beforņ°dONLNd¢›È)6e you r°dONLNd©› Èó)ead this book. In particular††°dONLNd≈›ñÈò)v,
  12541. °dONLNd«Ûä˙è(˘än
  12542. °dONLNd…ñ¸ú) Y@İdONLNd ú¸Œ) ou should r@°dONLNd’œ¸{)3$ead the information about QuickDraw '†°dONLNd˘{¸˚)¨GX shapes and objects in the °dONLNd¸ñ—(ñchapter  “Intr˘†°dONLNd$¸—<);oduction to QuickDraw }`°dONLNd:¸=^)lGX” in É¿°dONLNdA¸^€)!Inside Macintosh: QuickDraw ÿ¿°dONLNd]¸€
  12543. )}
  12544. GX Objects%İdONLNdg¸ )0. °dONLNdiñú(ñY@İdONLNdjú„)ou should also r, °dONLNdz„´)G-ead the chapter “Shape Objects” in that book.
  12545. °dONLNd®ä$è(#än
  12546. °dONLNd™ñ&≠) BeforÛ¿°dONLNdØ≠&À)e you ré °dONLNd∂Ã&Ÿ)=ead Chapter 3, “Geometric Styles,” in this book, you should r<‡°dONLNdÛ⁄&¸(#⁄ead the °dONLNd˚&ñ2
  12547. (/ñchapter “Style Objects” in ≤‡°dONLNd&
  12548. 2á)tInside Macintosh: QuickDraw ‡°dONLNd2&à2π)~ GX Objects.
  12549. 
  12550. °dONLNd>;äBè(Aän
  12551. °dONLNd@8ñDº) As you rU°dONLNdH8ºD)&Kead this chapter and the other chapters in this book, you might want to be °dONLNdìDñP>(Mñ'familiar with the other information in >¿°dONLNd∫D?Pº)©Inside Macintosh: QuickDraw ì¿°dONLNd÷DºPÎ)}
  12552. GX Objects‡Ä°dONLNd‡DÎP)/—in °dONLNd‰Pñ\¡(Yñ
  12553. particular4İdONLNdÓP¡\)+, you might also r`°dONLNdP\ê)Mead the “Ink Objects,” and “TúİdONLNdPè\)Åransform Objects” chapters in °dONLNd;\ñh¬(eñ
  12554. that book.°dONLNdFmäy¿(vä This chapterúİdONLNdRm¿yÚ)6 , which intr0°dONLNd^mÛy£)3'oduces the main concepts found in the r∂†°dONLNdÖm£y)∞est of this book, starts by °dONLNd°zäÜç(ÉärE°dONLNd¢zéÜe).eviewing the objects that make up a QuickDraw O°dONLNd–zeÜ√)◊GX shape and by intr:¿°dONLNd‰z√Ü˙)^ oducing the °dONLNdáäìñ(êädif™`°dONLNdÛáñì¢) fer凰dONLNdˆá¢ìH) 'ent types of graphic shapes. It then prȆ°dONLNdáHìø)¶ovides a brief discussion of
  12555. °dONLNd:ùä§è(£än
  12556. °dONLNd<öñ¶±) the str;`°dONLNdCö≤¶…)uctur¡@°dONLNdHö…¶8)e of the geometric shapes
  12557. °dONLNdbØä∂è(µän
  12558. °dONLNdd¨ñ∏T) *the contents of geometric shape geometries
  12559. °dONLNdè¡ä»è(«än
  12560. °dONLNdëæñ ») the shape fiD@°dONLNdùæ… €)3ll pr\ °dONLNd¢æ€ 5)operty and how it af=İdONLNd∂æ5 ò)Zfects geometric shapes
  12561. °dONLNdÕ”ä⁄è(Ÿän
  12562. °dONLNdœ–ñ‹∞) the pr§Ä°dONLNd’–∞‹®)9operties of the style object that modify geometric shapes
  12563. °dONLNdÂäÏè(Îän
  12564. °dONLNd‚ñÓ) the geometric operations prÄİdONLNd,‚Óu)zovided by QuickDraw Ó °dONLNd@‚uÓÉ)eGX
  12565. °dONLNdC˜ä˛è(˝än
  12566. °dONLNdEÙñ±) the str;`°dONLNdLÙ≤…)uctur¡@°dONLNdQÙ…)e of bitmap shapes
  12567. °dONLNdd    äè(än
  12568. °dONLNdfñ±) the str;`°dONLNdm≤…)uctur¡@°dONLNdr…ˆ) e of picturΩİdONLNd}ˆ)-e shapes
  12569. H34H3
  12570. CHK4DHK EHE
  12571. ˇ·ˇ‚7^
  12572. ˇˇ©ˇÆ°dONLNdá0HC/(>HAbout QuickDraw GX GraphicsˇˇˇˇˇˇVÌ(>1
  12573. °dONLNd§Tä`î(]äWÛ`°dONLNd•Tì`)    ith QuickDraw GX, you crŒ¿°dONLNdΩT`Y)teate graphics by cr[@°dONLNd–TZ`‚)Seating QuickDraw GX shapes. eİdONLNdÏT‚`    )àGraphic °dONLNdÙaäm©(jäshapesò°dONLNd˙a©mì)4 include geometric shapes, bitmap shapes, and picturİdONLNd.aîmª)Π   e shapes:
  12574. °dONLNd8wä~è(}än
  12575. °dONLNd:tñÄÁ) Geometric shapes⁄@°dONLNdJtÁÄÚ)Q ar@°dONLNdMtÛÄ ) @e the building blocks for graphics. These shapes, which include °dONLNdçÄñåˆ(âñpoints, lines, curves, rµ`°dONLNd•Ĉå
  12576. )`=ectangles, polygons, and paths, make up the graphic elements °dONLNd‚åñò(ïñsupported by most drawing pr≠@°dONLNd˛åòX)à ograms. Ther6@°dONLNd
  12577. åYòi);e arD‡°dONLNdåiò )&e also two special types of geometric °dONLNd4òñ§J(°ñ'shapes: empty shapes, which cover no arΔ°dONLNd[òJ§Ô)¥'ea, and full shapes, which cover all arp°dONLNdÇò§¸)¶ea.ˇ0\@ˇ ˇˇˇˇ@
  12578. ˇ·ˇ‚7^
  12579. 4*\¯, Palatino
  12580. &e.3+l"CHAPTER à)>1,     Helvetica
  12581.     ˇˇ—˚ˇÆ(@lIntroduction to QuickDraw ÷n)e GX Graphics4⁄*˙¯
  12582. (‡*1-4
  12583.     )BAbout QuickDraw GX Graphics
  12584. *Draft. PreliminaryVP):. ©bp)    1993Ù) §¿)Apple Computer¥0)6, Inc. ò–)12/15/934^*¿¯,
  12585.  
  12586. Zapf Dingbats
  12587. °dONLNd_lfq(eln
  12588. °dONLNd\xh∫)
  12589. Bitmap shapesj†°dONLNd\ªhú)C3 contain pixel images. These shapes allow you to cr§¿°dONLNdB\úhÊ)·eate graphics by °dONLNdShxt_(qx6specifying the color value of each pixel in the image.
  12590. °dONLNdä}lÑq(Éln
  12591. °dONLNdåzxÜπ) Picture shapesK °dONLNdöz∫Ü≈)B arê °dONLNdùz≈Ü?) e collections of QuickDraw ì¿°dONLNd∏z?Ü‘)z!GX shapes, including other pictur§`°dONLNdŸz‘Ü€)ïe °dONLNd€Üxíò(èxshapes.°dONLNd„ól£ˆ(†lAll QuickDraw GX shapes shar ¿°dONLNdˇó˜£L)ãe the same basic str†°dONLNdóL£c)Uuctur£Ä°dONLNdóc£é)
  12592. e. They ar˝°dONLNd"ó飶)+e all r\`°dONLNd)óߣµ)eprÌ °dONLNd,óµ£Ó)
  12593. esented by a °dONLNd9§l∞Ü(≠lCshape object and its associated style, ink, and transform objects. F°dONLNd|§á∞ü(≠áFigur¿°dONLNdŧü∞≥)e 1-1∂@°dONLNdܧ≥∞‰)  shows the °dONLNdë±lΩw(∫lstrfi°dONLNdî±wΩé) ucturc‡°dONLNdô±èΩÍ)e of the objects that r|İdONLNd∞±ÍΩ¯)[epr
  12594. @°dONLNd≥±˘ΩP)esent a QuickDraw B‡°dONLNd≈±PΩ})W    GX shape.
  12595. fl*¯4‡*¯"‡*]
  12596. ˇ·ˇ‚7^
  12597.     °dONLNdœ’l‡ñ(›l
  12598. Figure 1-1°dONLNd⁄’Ƈ)BShape object structure
  12599. °dONLNdÚllxÑ(ulFigurR¿°dONLNd˜lÑxò)e 1-1@°dONLNd¸lòx-)  shows the four basic QuickDraw óİdONLNdl.x°)ñGX objects and lists the prê°dONLNd7l°xÎ)soperties of each. °dONLNdIylÖá(ÇlThis fi$@°dONLNdPyàÖó)gurİdONLNdSyóÖ¯)e includes all of the prC†°dONLNdky˘Öè)b"operties of these objects. Howeverp°dONLNdçyèÖÎ)ñ, this book examines °dONLNd¢Ülí÷(èlonly a subset of these prG†°dONLNdªÜ◊í    )k operties. Pr{İdONLNd«Ü    í≠)2%operties not examined in this book arâ°dONLNdÏÜ≠íΩ)§e gr&¿°dONLNdÜæíÊ)    eyed out.°dONLNd˙òl§(°l%Like asll shapes, geometric shapes ar◊`°dONLNdò§)¢e rʰdONLNd"ò§') eprv¿°dONLNd%ò(§ )#esented by a shape object in memory°dONLNdHò §fi)¢. Thrø °dONLNdMòfi§ı)ee of °dONLNdS•l±Ü(Ælthe pr§Ä°dONLNdY•ܱÉ)7operties of the shape object—shape type, shape geometry¿Ä°dONLNdê•DZº)¸
  12600. , and shape fiîİdONLNdû•Ω±ˆ); ll—and how °dONLNd©≤læ.(ªl,they apply to geometric shapes in particularü°dONLNd’≤.æ;)¬, ard°dONLNdŸ≤<æS)e intrn¿°dONLNdfl≤Sæ£)oduced in section °dONLNdÒ≤£æÿ)P “Geometric 
  12601. jT¯4Ôijò@@¯@¯j0b¡¡?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Úò@@į@į0jpb?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Úò@Äú¯Äú¯pjåb?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Úòů@¯HHö˙‹Í9IJˇˇˇˇˇˇˇˇˇˇÃÃˇˇˇˇôôˇˇˇˇffˇˇˇˇ33ˇˇˇˇˇˇÃÃˇˇˇˇÃÃÃÃˇˇÃÃôô    ˇˇÃÃff
  12602. ˇˇÃÃ33 ˇˇÃà ˇˇôôˇˇ
  12603. ˇˇôôÃÃˇˇôôôôˇˇôôffˇˇôô33ˇˇôôˇˇffˇˇˇˇffÃÃˇˇffôôˇˇffffˇˇff33ˇˇffˇˇ33ˇˇˇˇ33ÃÃˇˇ33ôôˇˇ33ffˇˇ3333ˇˇ33ˇˇˇˇˇˇÃàˇˇôô!ˇˇff"ˇˇ33#ˇˇ$ÃÃˇˇˇˇ%ÃÃˇˇÃÃ&ÃÃˇˇôô'ÃÃˇˇff(ÃÃˇˇ33)ÃÃˇˇ*ÃÃÃÃˇˇ+ÃÃÃÃÃÃ,ÃÃÃÃôô-ÃÃÃÃff.ÃÃÃÃ33/ÃÃÃÃ0ÃÃôôˇˇ1ÃÃôôÃÃ2ÃÃôôôô3ÃÃôôff4ÃÃôô335ÃÃôô6ÃÃffˇˇ7ÃÃffÃÃ8ÃÃffôô9ÃÃffff:ÃÃff33;ÃÃff<ÃÃ33ˇˇ=ÃÃ33ÃÃ>ÃÃ33ôô?ÃÃ33ff@ÃÃ3333AÃÃ33BÃÃˇˇCÃÃÃÃDÃÃôôEÃÃffFÃÃ33GÃÃHôôˇˇˇˇIôôˇˇÃÃJôôˇˇôôKôôˇˇffLôôˇˇ33MôôˇˇNôôÃÃˇˇOôôÃÃÃÃPôôÃÃôôQôôÃÃffRôôÃÃ33SôôÃÃTôôôôˇˇUôôôôÃÃVôôôôôôWôôôôffXôôôô33YôôôôZôôffˇˇ[ôôffÃÃ\ôôffôô]ôôffff^ôôff33_ôôff`ôô33ˇˇaôô33ÃÃbôô33ôôcôô33ffdôô3333eôô33fôôˇˇgôôÃÃhôôôôiôôffjôô33kôôlffˇˇˇˇmffˇˇÃÃnffˇˇôôoffˇˇffpffˇˇ33qffˇˇrffÃÃˇˇsffÃÃÃÃtffÃÃôôuffÃÃffvffÃÃ33wffÃÃxffôôˇˇyffôôÃÃzffôôôô{ffôôff|ffôô33}ffôô~ffffˇˇffffÃÃÄffffôôÅffffffÇffff33ÉffffÑff33ˇˇÖff33ÃÃÜff33ôôáff33ffàff3333âff33äffˇˇãffÃÃåffôôçfffféff33èffê33ˇˇˇˇë33ˇˇÃÃí33ˇˇôôì33ˇˇffî33ˇˇ33ï33ˇˇñ33ÃÃˇˇó33ÃÃÃÃò33ÃÃôôô33ÃÃffö33ÃÃ33õ33ÃÃú33ôôˇˇù33ôôÃÃû33ôôôôü33ôôff†33ôô33°33ôô¢33ffˇˇ£33ffÃç33ffôô•33ffff¶33ff33ß33ff®3333ˇˇ©3333ÃÙ3333ôô´3333ff¨333333≠3333Æ33ˇˇØ33ÃÃ∞33ôô±33ff≤3333≥33¥ˇˇˇˇµˇˇÃÃ∂ˇˇôô∑ˇˇff∏ˇˇ33πˇˇ∫ÃÃˇˇªÃÃÃúÃÃôôΩÃÃffæÃÃ33øÃÿôôˇˇ¡ôôÃìôôôô√ôôffƒôô33≈ôôΔffˇˇ«ffÃûffôô…ffff ff33ÀffÃ33ˇˇÕ33ÃÃŒ33ôôœ33ff–3333—33“ˇˇ”ÃÑôô’ff÷33◊ÿˇˇˇŸ˘`˘`˘`⁄Ú–Ú–Ú–€Ï@Ï@Ï@‹Â∞Â∞Â∞›fl fl fl fiÿêÿêÿêfl“““‡ÀpÀpÀp·ƒ‡ƒ‡ƒ‡‚æPæPæP„∑¿∑¿∑¿‰±0±0±0™†™†™†Ê§§§ÁùÄùÄùÄËñññÈê`ê`ê`Íâ–â–â–ÎÉ@É@É@Ï|∞|∞|∞Ìv v v ÓoêoêoêÔiiibpbpbpÒ[‡[‡[‡ÚUPUPUPÛN¿N¿N¿ÙH0H0H0ıA†A†A†ˆ;;;˜4Ä4Ä4į---˘'`'`'`˙ – – –˚@@@¸∞∞∞˝
  12604.  
  12605.  
  12606.  ˛êêê@¯j0b'ÅÅÅâÅÅÅâàÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎèÎÅÅÅÏèÏÅÅÅÎèÎÅÅÅÎèÎÅÅÅÏèÎÅÅÅÎèÏÅÅÅÎèÎÅÅÅÏèÏÅÅÅÎèÎÅÅÅÎèÎÅÅÅÏèÎÅÅÅÎèÏÇ˝ˇÂˇÅüÎèÎÇÙˇËËÔˇÅüÏèÏÇÙˇËÁ¸ˇËËÁ˜ˇÅüÎèÎÇ˝ˇÚˇÁÁ˘ˇÅüÎèÎÇ˝ˇÂˇÅüÏèÎÇ˝ˇÎˇËÁ˝ˇÅüÎèÏDzˇ˛ÏˇÁË˝ˇÅüÎèÎDzˇ˛˚ˇ˚ÚˇÅüÏèÏÇ˝ˇ¸ˇ˙ÚˇÅüÎèÎÇ˝ˇ˝ˇ¯˙ˇ¸ˇÅüÎè!ÎÇ˝ˇ˛ˇ˛˛ˇ˛˙ˇ˛¸ˇÅüÏèÎǢˇ˛˝ˇ˛ˇ˙˚ˇÅüÎè&Ï硡¯˘ˇ˛˚ˇ¸ˇ˛ˇË˲ˇÅüÎè'Îç˚ˇ¸˘ˇ˙ˇ˛ˇˇ˝ˇÁ˲ˇÅüÏè#Ïç˜ˇ˘ˇ˛¸ˇ˛ˇˇ¯ˇÅüÎèÎñÊˇ˝¸ˇ˛ˇˇ¯ˇÅüÎè'Î󡡢˙ˇ˝˙ˇ¸˛ˇ˛˛ˇˇ¯ˇÅüÏè:Îòˇˇ¯ˇˇ¯˙ˇ˙ˇˇ˛ˇ˛¯ˇ˙˝ˇ˘ˇˇıˇˇ˛ˇˇÅ«Îè5ÏòˇÏ˘ˇ˜˛ˇ˜ˇ˚ˇˇ˝ˇ¸ˇˇıˇˇÛˇˇÅ“Îè=ÎòˇÏ¯ˇ˘˝ˇ˜ˇ˙˛ˇ¸ˇ˙ˇ˝˝ˇ˝ˇ¸ˇ˛ˇ˝ˇÅ”ÏèDÏòˇÏˇˇ˛¸ˇ˘˛ˇˇˇ˙ˇ¯ˇˇˇˇ˜ˇˇˇ˝ˇ¯ˇˇˇˇˇÅ“ÎèJÎòˇÏˇˇ˚˝ˇ˚ˇˇ˚˙ˇ˚ˇˇ˝ˇ˛ˇ˛ˇ¸ˇˇ˝ˇ¸ˇˇˇ˝ˇˇÅ“ÎèBÎòˇÏˇˇ¸˙ˇ˝ˇ¸˝ˇ˛ˇˇ˙˝ˇ˚ˇ˚ˇ˛˝ˇ˝ˇ˜ˇ˛ˇÅ”Ïè/ÎòˇÏˇ¸˘ˇ˝ˇ˚ˇ˝ˇˇÒˇˇÌˇˇÅ«Îè,ÏòˇÏ˛ˇ˜ˇ˛˘ˇ¸ˇˇÚˇˇÏˇˇÅ«ÎèÎòˇÏÚˇ˛˙ˇ¸˛ˇÅüÏèÏòˇÏÛˇ˝˚ˇ¸˝ˇÅüÎè!ÎòˇÏ˛ˇ¯ˇ˛˚ˇ¸¸ˇÅüÎè ÎòˇÏ˛ˇ˛˘ˇ˛¸ˇ¸˚ˇÅüÏèÛÎòˇÏ˛ˇ˝¸ˇ˝˚ˇ˝˙ˇÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÙÎè(ÏòˇÏˇˇÙ˙ˇ˛˘ˇÿÎøÎöÎÎıÎè(ÎòˇÏˇˇˆ¯ˇ˛˘ˇÿÎøÏöÏÎıÏèÏòˇÏ‡ˇÿÎøÎöÎÎıÎèÎòˇ‚Ï¬ÏøÎöÎÏıÎèÎòˇ‚Î¬ÎøÏöÏÎıÏèÎòˇ‚Ï¬ÏøÎöÎÏıÎèDÏòˇ‚΢˛ˇÔˇ˝ˇ˛ˇÈ΢ÎÏ˛Î˜Î◊ίÎÏÎfiΠÎÎıÎèHÎòˇ‚΢ˇˇÎˇˇˇÈίÎϘÎ◊ϯÏÎÁÏ˙Ï ÏÎıÏèzÏòˇ‚΢ˇˇˇˇ˛ˇ˛ˇˇˇˇ¯ˇÎÎ¯Ï˝
  12607. ÎÎÏÎÎÎÎÿί ÎÎÏÎÏÎθ ÏÎÏÎÎÏÎÏ˛Î
  12608. ÎÎÎÏÎΜÎÎıÎèÎòˇ‚Ï˘˛ˇ˝ˇˇˇˇˇˇˇˇˇˇˇˇˇÏϯ
  12609. ÎÎÏÎÎÎÏÎÎ÷ί˛Î    ÎÎÎβÎÏÎÏÎÏÎÏÎÎÎÎÎÕÎÏıÎèÑÎòˇ‚΢ˇ˛ˇ˝ˇˇ˛ˇˇˇˇˇˇˇˇˇÏÎ˘Ï˝
  12610. ÎÏÏÏÎÏÎ◊ϯ ÏÎÎÏÎÏ˛Ï˛ÏÎÏÎÏÎÎÏÏ˛ÏΜÏÎıÏèÎòˇ‚Ï˘ˇ˝˛ˇˇˇ˛ˇˇˇ˛ˇˇˇˇÏÏ˘ÎνÎÏÎÎÎ÷ί ÎÏÎÏÎÎν
  12611. ÎÎÏÎÎÎÏ˛ÏÎÏÎ˛ÎŒÎÏıÎèÏòˇ‚Î¬ÎøÎöÎÎıÎèÎòˇ‚Î¬ÎøÏöÏÎıÏèÏòˇ‚Î¬ÎøÎöÎÎıÎè˛Îòˇ‚Ï˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏıÎèÎòˇ‚Î¬ÎøÏöÏÎıÏèÎòˇ‚Ï¬ÏøÎöÎÏıÎèÏòˇ‚Î¬ÎøÎöÎÎıÎèÎòˇ‚Î¬ÎøÏöÏÎıÏèòů@įHHö˘àÍ:IJˇˇˇˇˇˇˇˇˇˇÃÃˇˇˇˇôôˇˇˇˇffˇˇˇˇ33ˇˇˇˇˇˇÃÃˇˇˇˇÃÃÃÃˇˇÃÃôô    ˇˇÃÃff
  12612. ˇˇÃÃ33 ˇˇÃà ˇˇôôˇˇ
  12613. ˇˇôôÃÃˇˇôôôôˇˇôôffˇˇôô33ˇˇôôˇˇffˇˇˇˇffÃÃˇˇffôôˇˇffffˇˇff33ˇˇffˇˇ33ˇˇˇˇ33ÃÃˇˇ33ôôˇˇ33ffˇˇ3333ˇˇ33ˇˇˇˇˇˇÃàˇˇôô!ˇˇff"ˇˇ33#ˇˇ$ÃÃˇˇˇˇ%ÃÃˇˇÃÃ&ÃÃˇˇôô'ÃÃˇˇff(ÃÃˇˇ33)ÃÃˇˇ*ÃÃÃÃˇˇ+ÃÃÃÃÃÃ,ÃÃÃÃôô-ÃÃÃÃff.ÃÃÃÃ33/ÃÃÃÃ0ÃÃôôˇˇ1ÃÃôôÃÃ2ÃÃôôôô3ÃÃôôff4ÃÃôô335ÃÃôô6ÃÃffˇˇ7ÃÃffÃÃ8ÃÃffôô9ÃÃffff:ÃÃff33;ÃÃff<ÃÃ33ˇˇ=ÃÃ33ÃÃ>ÃÃ33ôô?ÃÃ33ff@ÃÃ3333AÃÃ33BÃÃˇˇCÃÃÃÃDÃÃôôEÃÃffFÃÃ33GÃÃHôôˇˇˇˇIôôˇˇÃÃJôôˇˇôôKôôˇˇffLôôˇˇ33MôôˇˇNôôÃÃˇˇOôôÃÃÃÃPôôÃÃôôQôôÃÃffRôôÃÃ33SôôÃÃTôôôôˇˇUôôôôÃÃVôôôôôôWôôôôffXôôôô33YôôôôZôôffˇˇ[ôôffÃÃ\ôôffôô]ôôffff^ôôff33_ôôff`ôô33ˇˇaôô33ÃÃbôô33ôôcôô33ffdôô3333eôô33fôôˇˇgôôÃÃhôôôôiôôffjôô33kôôlffˇˇˇˇmffˇˇÃÃnffˇˇôôoffˇˇffpffˇˇ33qffˇˇrffÃÃˇˇsffÃÃÃÃtffÃÃôôuffÃÃffvffÃÃ33wffÃÃxffôôˇˇyffôôÃÃzffôôôô{ffôôff|ffôô33}ffôô~ffffˇˇffffÃÃÄffffôôÅffffffÇffff33ÉffffÑff33ˇˇÖff33ÃÃÜff33ôôáff33ffàff3333âff33äffˇˇãffÃÃåffôôçfffféff33èffê33ˇˇˇˇë33ˇˇÃÃí33ˇˇôôì33ˇˇffî33ˇˇ33ï33ˇˇñ33ÃÃˇˇó33ÃÃÃÃò33ÃÃôôô33ÃÃffö33ÃÃ33õ33ÃÃú33ôôˇˇù33ôôÃÃû33ôôôôü33ôôff†33ôô33°33ôô¢33ffˇˇ£33ffÃç33ffôô•33ffff¶33ff33ß33ff®3333ˇˇ©3333ÃÙ3333ôô´3333ff¨333333≠3333Æ33ˇˇØ33ÃÃ∞33ôô±33ff≤3333≥33¥ˇˇˇˇµˇˇÃÃ∂ˇˇôô∑ˇˇff∏ˇˇ33πˇˇ∫ÃÃˇˇªÃÃÃúÃÃôôΩÃÃffæÃÃ33øÃÿôôˇˇ¡ôôÃìôôôô√ôôffƒôô33≈ôôΔffˇˇ«ffÃûffôô…ffff ff33ÀffÃ33ˇˇÕ33ÃÃŒ33ôôœ33ff–3333—33“ˇˇ”ÃÑôô’ff÷33◊ÿˇˇˇŸ˘`˘`˘`⁄Ú–Ú–Ú–€Ï@Ï@Ï@‹Â∞Â∞Â∞›fl fl fl fiÿêÿêÿêfl“““‡ÀpÀpÀp·ƒ‡ƒ‡ƒ‡‚æPæPæP„∑¿∑¿∑¿‰±0±0±0™†™†™†Ê§§§ÁùÄùÄùÄËñññÈê`ê`ê`Íâ–â–â–ÎÉ@É@É@Ï|∞|∞|∞Ìv v v ÓoêoêoêÔiiibpbpbpÒ[‡[‡[‡ÚUPUPUPÛN¿N¿N¿ÙH0H0H0ıA†A†A†ˆ;;;˜4Ä4Ä4į---˘'`'`'`˙ – – –˚@@@¸∞∞∞˝
  12614.  
  12615.  
  12616.  ˛êêê@į0jpb'Ïòˇ‚Î¬ÎøÎöÎÎıÎè$Îòˇ‚ϯˇˇÕÏøÎöÎÏıÎèDÎòˇ‚Î˙ˇˇˇŒÎ˘ÏÎÏÎÏÚÏ‹Ï˘ÎÏÎıÏÓÏÎ…ÏÎıÏèIÎòˇ‚Ï˙ˇ˚ˇˇ˛ˇ÷Ï˜ÎˆÎ˝Ï€Î˘ÏÎflÎıÎÒÎÊÎÏıÎèßÏòˇ‚Î˙ˇ¸¸ˇˇ◊Î˜Î˛ ÎÎÏÎÏÎβΠ   ÏÎÏÎÏÎÊ΢ÎνÏÎÏ˛ÎÏÎÏÎβÎÎÏ˝ÎβÎÏÎÎÏ˛ÎÏÎÎÏ˝
  12617. ÎÎÏÎÎÏÎÎÏÎβÎÎÎÎÏÎÏÎÎÎÎÎıÎèÆÎòˇ‚Î˙ˇ˛    ˇˇˇˇˇ◊Θ ÏÎÏÎÏÏÎÏ˝ ÎÏÎÏÎÏÎÏÎÏÎÁÏ˘ÎÎÏÎÏÎÎÎÏÏÎÏÏβÎÏÎÏÎÏÎÎÏÏβÎÏÏÏÎÏÎÏÎÏÏÏνÏÎÏÎÏÎÏÎÏÎÏÎÏÎıÏè°Ïòˇ‚΢˛ˇ˛˚ˇ÷ΘÎÏ˝ÎÎνÎÎÎβΉ΢ÎÎνÏÎÎÎÏÎÎÏ˛
  12618. ÏÎÏÎÏÎβ ÎÎÏÎÎÎÏ˛ÏÎβÎÎÎÏÎÏÎÎÏÎÎÎıÎèüÎòˇ‚Ïˇ‘Ï˜Î˛    ÎÏÎÎÎÏ˛ ÏÎÎÏÎÎÏÎÎÏÁÎ˘Ï˛ÏÎÎÏÎÏÎÎÎÎÏÎν    ÎÏÎÎÏÎβββÎÎβ    ÎÏÎÎÎÏ˛Î˝Ï˛ÎβÎÎÏÎβÎÏıÎè/Îòˇ‚Îˇ‘ÎøÏflÎˆÎŒÎ˝ÏÎıÏè-Îòˇ‚Ï¬ÏøÎ‚ÎÏΈΌθÎÏıÎèÏòˇ‚Î¬ÎøÎöÎÎıÎèÎòˇ‚Î¬ÎøÏöÏÎıÏè˛Ïòˇ‚ÎÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏÎÎıÎèÎòˇ‚Ï¬ÏøÎöÎÏıÎèÎòˇ‚Î¬ÎøÏöÏÎıÏèÎòˇ‚Ï¬ÏøÎöÎÏıÎèÏòˇ‚Î¬ÎøÎöÎÎıÎè'Îòˇ‚Θˇ˝ˇ“ÎøÏöÏÎıÏèFÏòˇ‚ΘˇÕ΢ÎÏ˛ÎÒϛΘÏÎÎϯÎÛΘϯÎ◊ÎÎıÎèPÎòˇ‚Ϙˇˇˇˇ˛ˇ÷ϘΈÎ÷Î¯Î˛ÎίÏÛÎ¯Î˛Î¸Î÷ÎÏıÎè£Îòˇ‚Θ
  12619. ˇˇˇˇˇˇ◊ΘÏÎÏÎÏÎÏÎÏÎÏÎÎÏÎÏÏÎÂÏ˘Î¸ ÎÎÏÎÏÎÎÏθ    ÎÏÎÏÎÏÎÏ˛ÏÎÏÎÏÎÎÏÎÏÎÏÎÏÎÏÎÏÎÏβÎÏÎÏÎÏÎÏÎÏ˙ÏÎıÏè®Îòˇ‚Ï˙
  12620. ˇˇˇˇˇˇˇ◊ϘβÎÏÎÏÎÎÎβÎÏ˛ÎÊ΢ÏÎÏÎÎÏÎÏÎÏβÎÏÎÎÎÎÏβÎÎÎÎÎÎÏÎÎÎÎÎÏ˝˛ÎÏÎÏÎÏÎÎÏÎ˙ÎÏıÎè¢Ïòˇ‚΢ ˇˇˇˇˇˇˇ◊ΘÎθÎÎνÎÎÏÎ΄΢ÎβÎÏÎÎÎÎÎθ    ÎÏÎÏÎÏ˛1ÏÎÎÏÎÏÎÎÎÏÎÎÏÎÏÎÎÏÎÎÏÎÎ˙ÎÎıÎèñÎòˇ‚άΘÏÎÏÎÎÏÎÎÏÎÎÎÏÎÏÏÎÏÊϘÎÏÎÏÎÏÎÎÏÎÎÏ˛ÏÎÏÎÏÎÏÎÏÎÏββÎÏÎÏÎÏÎÏÎÏÎÏ˝ÎÏÎÎβÎÏÎÏ΢ÏÎıÏè*Ïòˇ‚Î¬ÎøÎÎÎπίÎÎıÎè+Îòˇ‚Ï¬ÏøÎÒÏ˛Ï∫ϘÎÏıÎèÎòˇ‚Î¬ÎøÏöÏÎıÏè˛Îòˇ‚Ï˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏıÎèÏòˇ‚Î¬ÎøÎöÎÎıÎèÎòˇ‚Î¬ÎøÏöÏÎıÏèÏòˇ‚Î¬ÎøÎöÎÎıÎèÎòˇ‚Ï¬ÏøÎöÎÏıÎèÎòˇ‚Î¬ÎøÏöÏÎıÏè8Îòˇ‚Ï˘˛ˇ˜ˇÿϘÎÎϜί˛ÎÛεÎÏıÎèEÏòˇ‚΢ˇˇ¯ˇÿίÏÎÏÂÎÍίÎÎıΈοÎÎıÎèñÎòˇ‚΢    ˇˇˇˇ˚ˇ⁄ίÎÎÎÎÎÏÎÎÏÎÎÏÏ˝
  12621. ÎÏÏÎÏÎÏÎÎϯ ÏÎÏÎÎÏβÎÏÎÎÏÎÏÎÏÎÏÎÏÎÏÎÏνÏÎÎÏÏÎÎÏÎωÏÎıÏèóÏòˇ‚΢ˇˇ˚ˇˇˇ€Î¯ÏÎÎÏÎÎÎÏÎÏÎÏÎÏ˛ÎÎÎÍί ÎÏÎÎÎÏββÎÏ˛Î ÏÎÏÎÏÎÏ˛ÎϸÎÎÏÎÎÎÎÏÎÎÏΉÎÎıÎèõÎòˇ‚Ï˘
  12622. ˇˇˇˇ˛ˇˇ€Ï˘Î˛ÎÎÏÎÏÎÎÎÏÎβÎÏÎÍί ÎÏÎÏÎβÎβÎÎÎÎÎÎθÎÏ˛ÏÎÏÎÎÏÎΉÎÏıÎèïÎòˇ‚΢˛ˇ˛˚ˇˇˇ€Î˘Ï˛ÏÎÎÎÏÎÎÏÎÎβÎÏÎÏβÎÎϯ ÏÎÎÏÎÎÏ˛    ÏÎÏÎÎÏβÎÏÎÏβÎÏÎÏÎϸÏÎÏÎÏÎÏÎÏ΄ÏÎıÏè'Îòˇ‚ϬÏÓÏ”Î∫΂ÎÏıÎè)Ïòˇ‚άÎÒÎÏΓΪϷÎÎıÎèÎòˇ‚Î¬ÎøÏöÏÎıÏèÏòˇ‚Î¬ÎøÎöÎÎıÎèΈ‡ˇƒˇ‚Ï˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏıÎè<Έ˚ˇ˝ˇ‰‰„˛‰„˛‰„˝˛‰„‰ˇƒˇ‚Î¬ÎøÏöÏÎıÏè:Έ¸ˇ˙ˇ‰ˇˇ„ˇˇ‰ˇˇ˝˛ˇ‰ˇˇƒˇ‚Ï¬ÏøÎöÎÏıÎè:ψ˝ˇ˘ˇ‰ˇˇ‰ˇˇ‰ˇˇ¸ˇˇ‰ˇˇƒˇ‚Î¬ÎøÎöÎÎıÎè9Έ˝ˇ˙ˇ„˛‰„˛‰„‰‰˚˛‰ˇƒˇ‚Î¬ÎøÏöÏÎıÏè;ψ˛ˇ¯ˇ‰ˇˇ‰ˇˇ‰ˇ˘‰ˇˇƒˇ‚΢˛ˇÕÎøÎöÎÎıÎèoΈ˛ˇ˜ˇ‰ˇˇ„ˇˇ‰ˇ¯ˇˇƒˇ‚Ï˘ˇˇ¸ˇˇ◊Ï˘˛ÎÏËÎ˙ÎÌ΢ÏÎÎ˝Î˘Ï¯ÎıÎ˛ÎˆÎ⁄ÎÏıÎènΈˇˇ˘ˇ‰‰„˛‰„˛‰¯‰ˇƒˇ‚΢ˇˇˇˇ˘ˇˇˇ˛ˇ·Î˘ÏÙÏÏÏÏÏ˘ÎÏÚÏÔÎ˛ÎˆÎŸÏÎıÏèƒΈˇˇˆˇ‰ˇˇ„ˇˇ‰ˇ˜ˇƒˇ‚Ï˘˛ˇ˝ˇˇ˚ˇˇˇ‚Ï˘Î˝(ÎÎÎÎÏÎÎÏÎÎÏÎÎÏÎÏÎÏÎÎÎÎÏÎβÎÎÏ˚΢ÏβÎÎÎÎÎÏÎÎÏÎÎÏÎÎÎÏ˛Î˛ÎÎÎÎβÎÎÎÎÎÏ„ÎÏıÎè»ψˇˇˆˇ‰ˇˇ‰ˇˇ‰ˇ˜ˇƒˇ‚΢ˇ˛    ˇˇˇˇˇ˛ˇˇˇ‚΢ÎÏ˛Î    ÎÏÎνÎÏ˛ÎÏÎÏ˛ÎÏÎÏÎÎÎÎÎÏ˘Î˘"ÎÎÏÎÎÎÎÏÎÎÎÎÏÎÎÎÏ˛ÏÎÏÎÎÎÎÏÎÎÏÎÎÎÏΉÎÎıÎè…Έˇˇˆˇ‰ˇˇ‰ˇˇ„ˇ˛ˇ˚ˇƒˇ‚΢ˇ˝˛ˇˇ¸ˇˇˇ‚Î˘Ï˛
  12623. ÏÎÎÏÏ˝ÎÏÏÎÏÎÏÎÏÎÎÏÎÏ˛ÏÎ˚Ï˘Î˝ÏÏÏÎÎÎÏÏÏÎÎÏ˛
  12624. ÏÎÎÏÎÏÏ˛ÏÎÎÏÏÎÎωÏÎıÏè©ψˇˇÓˇ˛ˇˇ¸ˇƒˇ‚ά΢ν
  12625. ÏÎÏÎββ
  12626. ÎÎÏÎÏÎÎÏ˛
  12627. ÏÎÏÎÎÎÏÎ˙΢ν ÎÎÏÎÏβÎÎÏ˛    ÏÎÏÎÎÏβÎÏÎÏÎÎÏÎÎÎÏÎÏΉÎÎıÎè<Έˇˇˆˇ‡˙ˇ˛ˇˇ¸ˇƒˇ‚Ï¬ÏøÎ‰Î˝ÎΩÎÏıÎè;Έˇˇ˙ˇ¸‡˚ˇ˛˛ˇ¸ˇƒˇ‚Î¬ÎøÏÂÎ˝ÏºÏÎıÏè;Έˇˇ˛ˇ˛‡fl˛‡fl‡‡¸ˇ˛˛ˇ¸ˇƒˇ‚Ï¬ÏøÎöÎÏıÎè@ψˇˇˇ˛‡fl˛‡fl˛‡fl¸ˇˆˇƒˇ‚Î¬ÎøÎÁÏ˛ÏπÎÎıÎèÆΈˇ‡‡ˇı‡¸ˇˆˇƒˇ‚ÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏ„ÎπÏÎıÏèlψˇ‡‡ˇˇ‡‡fl˛‡fl˛‡fl¸ˇ˚˝ˇˇ˚˝ˇˇˇÍˇˇ˛ˇˇˇ‚Î¬ÎøÎ˘ÎÎÎÎÎÏÎÎÎÎÏÎÎÏÎÏΩÎÎıÎèpΈˇfl‡‡ˇˇ˛‡fl˛‡fl˛‡˝ˇ˛ˇ˙ˇ¸ˇˇˇˇˇˇÍˇˇÛˇˇ˚ˇ‚Ï¬ÏøÎ˙    ÎÎÎÎÏ˛Î ÏÎÎÎÎÏ˛ÎæÎÏıÎèpΈˇ˛‡ˇˇ˜‡˝ˇ¸˙ˇ˚˛ˇ˛˙ˇ˝ˇ˛ˇ˛˝ˇ˝ˇ¸ˇ˙ˇ¸ˇ‚Î¬ÎøÏ˙    ÏÎÏÎβ ÎÏÎÏÎΪÏÎıÏèuΈˇfl˛‡ˇ‡‡fl˛‡fl˛‡˛ˇ¸˘ˇ˘ˇˇ˘ˇˇˇ˚ˇˇˇ˝ˇ˜ˇ˝ˇ˚ˇ‚Ï¬ÏøÎ˘Ïββ˛Î ÏÎÎÏÎÎ˛ÎæÎÏıÎèòůÄú¯HHö˙‹Í;IJˇˇˇˇˇˇˇˇˇˇÃÃˇˇˇˇôôˇˇˇˇffˇˇˇˇ33ˇˇˇˇˇˇÃÃˇˇˇˇÃÃÃÃˇˇÃÃôô    ˇˇÃÃff
  12628. ˇˇÃÃ33 ˇˇÃà ˇˇôôˇˇ
  12629. ˇˇôôÃÃˇˇôôôôˇˇôôffˇˇôô33ˇˇôôˇˇffˇˇˇˇffÃÃˇˇffôôˇˇffffˇˇff33ˇˇffˇˇ33ˇˇˇˇ33ÃÃˇˇ33ôôˇˇ33ffˇˇ3333ˇˇ33ˇˇˇˇˇˇÃàˇˇôô!ˇˇff"ˇˇ33#ˇˇ$ÃÃˇˇˇˇ%ÃÃˇˇÃÃ&ÃÃˇˇôô'ÃÃˇˇff(ÃÃˇˇ33)ÃÃˇˇ*ÃÃÃÃˇˇ+ÃÃÃÃÃÃ,ÃÃÃÃôô-ÃÃÃÃff.ÃÃÃÃ33/ÃÃÃÃ0ÃÃôôˇˇ1ÃÃôôÃÃ2ÃÃôôôô3ÃÃôôff4ÃÃôô335ÃÃôô6ÃÃffˇˇ7ÃÃffÃÃ8ÃÃffôô9ÃÃffff:ÃÃff33;ÃÃff<ÃÃ33ˇˇ=ÃÃ33ÃÃ>ÃÃ33ôô?ÃÃ33ff@ÃÃ3333AÃÃ33BÃÃˇˇCÃÃÃÃDÃÃôôEÃÃffFÃÃ33GÃÃHôôˇˇˇˇIôôˇˇÃÃJôôˇˇôôKôôˇˇffLôôˇˇ33MôôˇˇNôôÃÃˇˇOôôÃÃÃÃPôôÃÃôôQôôÃÃffRôôÃÃ33SôôÃÃTôôôôˇˇUôôôôÃÃVôôôôôôWôôôôffXôôôô33YôôôôZôôffˇˇ[ôôffÃÃ\ôôffôô]ôôffff^ôôff33_ôôff`ôô33ˇˇaôô33ÃÃbôô33ôôcôô33ffdôô3333eôô33fôôˇˇgôôÃÃhôôôôiôôffjôô33kôôlffˇˇˇˇmffˇˇÃÃnffˇˇôôoffˇˇffpffˇˇ33qffˇˇrffÃÃˇˇsffÃÃÃÃtffÃÃôôuffÃÃffvffÃÃ33wffÃÃxffôôˇˇyffôôÃÃzffôôôô{ffôôff|ffôô33}ffôô~ffffˇˇffffÃÃÄffffôôÅffffffÇffff33ÉffffÑff33ˇˇÖff33ÃÃÜff33ôôáff33ffàff3333âff33äffˇˇãffÃÃåffôôçfffféff33èffê33ˇˇˇˇë33ˇˇÃÃí33ˇˇôôì33ˇˇffî33ˇˇ33ï33ˇˇñ33ÃÃˇˇó33ÃÃÃÃò33ÃÃôôô33ÃÃffö33ÃÃ33õ33ÃÃú33ôôˇˇù33ôôÃÃû33ôôôôü33ôôff†33ôô33°33ôô¢33ffˇˇ£33ffÃç33ffôô•33ffff¶33ff33ß33ff®3333ˇˇ©3333ÃÙ3333ôô´3333ff¨333333≠3333Æ33ˇˇØ33ÃÃ∞33ôô±33ff≤3333≥33¥ˇˇˇˇµˇˇÃÃ∂ˇˇôô∑ˇˇff∏ˇˇ33πˇˇ∫ÃÃˇˇªÃÃÃúÃÃôôΩÃÃffæÃÃ33øÃÿôôˇˇ¡ôôÃìôôôô√ôôffƒôô33≈ôôΔffˇˇ«ffÃûffôô…ffff ff33ÀffÃ33ˇˇÕ33ÃÃŒ33ôôœ33ff–3333—33“ˇˇ”ÃÑôô’ff÷33◊ÿˇˇˇŸ˘`˘`˘`⁄Ú–Ú–Ú–€Ï@Ï@Ï@‹Â∞Â∞Â∞›fl fl fl fiÿêÿêÿêfl“““‡ÀpÀpÀp·ƒ‡ƒ‡ƒ‡‚æPæPæP„∑¿∑¿∑¿‰±0±0±0™†™†™†Ê§§§ÁùÄùÄùÄËñññÈê`ê`ê`Íâ–â–â–ÎÉ@É@É@Ï|∞|∞|∞Ìv v v ÓoêoêoêÔiiibpbpbpÒ[‡[‡[‡ÚUPUPUPÛN¿N¿N¿ÙH0H0H0ıA†A†A†ˆ;;;˜4Ä4Ä4į---˘'`'`'`˙ – – –˚@@@¸∞∞∞˝
  12630.  
  12631.  
  12632.  ˛êêêÄú¯pjåb'nψ ˇ‡‡fl‡‡ˇˇ‡‡fl˛‡fl‡˛ˇ˝˙ˇˇ¸ˇˇˇˇ¸ˇˇˇˇˇ˛ˇ˝ˇˇ˝ˇ¸ˇ˛ˇˇ˛ˇˇ˚ˇ‚ίˇˇÕÎøÎöÎÎıÎèfΈˇ˚‡˝ˇ˙‡ˇˇ˝¯ˇ˚˝ˇ˘ˇ˝ˇ˝ˇ˝ˇ˝ˇ˚ˇ˙ˇ¸ˇ‚Î˙ˇˇˇŒÎ˘ÏÎÏÎÎÏfiÏöÏÎıÏèlψˇ‡‡fl˛‡fl‡¸ˇfl˜˙ˇÏˇˇÓˇˇˇ‚Î˙ˇ˝ˇˇ˛ˇˇˇˇ¸ˇˇ˝ˇˇˇˇˇ΢ÎÌÏ›ÎöÎÎıÎèÈΈˇfl˛‡fl˛‡fl˛‡˝ˇ¯˚ˇÏˇˇÓˇˇˇ‚Ï˙ˇ˝    ˇˇˇˇ¸ˇ˛˝ˇ
  12633. ˇˇˇˇˇÔÏ˘Î˝
  12634. ÎÎÏÎÏÎÏ˛Ï˛Î˛ÎÎÎÏÁÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏıÎèuΈˇ‡¸¸ˇ˝ˇƒˇ‚Î˙ˇ˛ ˇˇˇˇˇˇˇ˚ˇ˝    ˇˇˇˇˇÔ΢ÏÎÏÎÎÏÎÏÎÏÏÎÏÏÎÏÎÁÏöÏÎıÏèÅΈˇfl˛‡fl˛‡fl˛‡fl˛‡fl¸ˇ˝˝ˇƒˇ‚Ï˘˛ˇ˛ˇˇˇ˛˛ˇ˝˛ˇˇˇ˛ˇˇˇÔÏ˘Î˝ÎÎβÎÎÎÎÎÎÏÎÏÁÎöÎÏıÎè^ψˇ‡‡fl˛‡fl˛‡fl˛‡fl˛‡ˇˇ¸˙ˇƒˇ‚ά΢    ÎÏÎÎÏβÎÎβ ÎÎÏÎÎÎÏÎÎÁÎöÎÎıÎè/ΈˇÒ‡˝ˇˆˇƒˇ‚άÎ⁄ÎÁÏöÏÎıÏèYψˇ‡‡fl˛‡fl˛‡fl‡¸ˇ‡flÃˇÏˇ‚άΛÎÏÎÊίÎÏÎϯθÏıÎ˛ÎˆÎ÷ÎÎıÎèUΈˇfl˛‡fl˛‡fl˝ˇ˛‡fl‡‡Ùˇ⁄ˇˇÌˇ‚Ï¬ÏøÎ˘Ï˛ÏίÏÎ˛ÎˆÎ’ÎÏıÎèjΈˇÓ‡Ùˇ⁄ˇˇÌˇ‚Î¬ÎøÏ˙Ï˚ ÎÏÎÏÎÏÎÏβ&ÎÎÏÎÏÎÏÎÏÏÎÏÎÏÎÏÏÎÏÎÏÎÏÎflÏÎıÏè˘Έˇfl˛‡fl˛‡fl˛‡fl˛‡fl‡‡Ùˇ⁄ˇˇÌˇ‚Ï˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛Î˙ÎÎÎÏÎÎÎÎÎÏÎÎÏÎÎβ
  12635. ÎÎÎÎÎÏ˛Î
  12636. ÏÎÎÎÏηÎÏıÎèjψ‡ˇ⁄ˇˇÌˇ‚Î¬ÎøÎ˙ÎβÎÏÎÏÎÏÎÎÏÎβ
  12637. ÎÎÏÎÏÎβÎÎÏÎÎÎÏ·ÎÎıÎèhÎÓˇ¬ˇˇÌˇ‚Î¬ÎøÏ¯ÏÎÏÎÎÎÏÏÎÏÎÏÎÏÎÏÏÎÏ˛ÏÎÏÎÏÎÎÏÎÏÎÏÎχÏÎıÏè3ÏÓˇ¬ˇˇÌˇ‚Î¬ÎøÎÒÎΘÏπÎÎıÎè8ÎÓˇ˘¸ˇœˇˇÌˇ‚Ï¬ÏøÎÚÎ˛Î¯Î∏ÎÏıÎèCÎÓˇ˜ˇÕˇˇÌˇ‚ίˇ¯ˇˇÿÎ˙ÎÏÎÏÎËÎÏÊÏöÏÎıÏèiÎÓˇ˜ˇˇ˝ˇˇˇ⁄ˇˇÌˇ‚Ï˘ˇˇˇˇ¸ˇ¯ˇ‚ϯÎı΢ÏÎ˝Î¯ÎÎÁβÎπÎÏıÎèåÏÓˇ˜    ˇˇˇˇ¸ˇ€ˇˇÌˇ‚΢ˇˇ˚ˇˇ˛ˇˇˇ¸ˇ˛ˇÍÎ¯Ï˛ÏÎÏÎÏÎÎÎβÎÏÎÎÏ˛ÎβÎÏÎÎÎÎÏ˘Î„ÏπÎÎıÎèºÎÓˇ˜ˇ˛ˇˇˇˇˇÿˇˇÌˇ‚΢˛ˇˇˇˇˇˇˇˇˇ˙ˇËί.ÎÏÎÏÎÏÎÏÎÏÎÏÎÎÏÎÏÎÎÏÏÏÎÏÎÏÎ˜Ï˘ÎÏÎÏÏÎÎÏÏÎÎÎÏÎÏÎÏÎÏ˛ÏÎÏÎÎÏÏÎÏÎ◊ÏÎıÏè¬ÏÓˇ˜ˇ˛ˇˇ˛ˇ˛ˇ€ˇˇÌˇ‚Î˙ˇ˛ˇˇˇˇˇˇˇˇˇˇˇ¸ˇˇÍίÏθ ÎÎÎÏÎÎÏÎÏÎÏÎÎÎθÎÏ˘Î˙ÎÏβÎÏÎÎÎÏÎÏÎÎÏ˛Î˝Ï˛ÎÎÏÎÎÏÎÎÎ◊ÎÎıÎè¥ÎÓˇÛˇˇ‘ˇˇÌˇ‚Ï˙ˇ˛    ˇˇˇˇ˛ˇ˛ˇ˛˙ˇÈÏ¯Î˛ÎÎÏÎÎÏÎÏβÎÎÎÎÏβ˛ÎÎÏ˛ÎÏίÎ˙    ÎÎÎÎÏ˛ ÏÎÎÎÎϸÎÎÎÎÎÎÏÎÎÏ◊ÎÏıÎèfÎÓˇÙˇ˛ˇ‘ˇˇÌˇ‚Î¬ÎøÏ˘ÎÏ˛Ï˛ÏÎÏÎÏÎÎÏÎÏÎÏÎÏνÏÎÏÏÎÏÎÏÎÏ÷ÏÎıÏè,ÎÓˇ¬ˇˇÌˇ‚Ï¬ÏøÎ«Î’ÎÏıÎè'ÏÓøˇÌˇ‚Î¬ÎøÎ»Î‘ÎÎıÎè(ÎÓˇ¬ˇˇÌˇ‚Î¬ÎøÏöÏÎıÏèÏÓˇ¬ˇˇÌˇ‚ÎÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏÎÎıÎè"ÎÓˇ¬ˇˇÌˇ‚ÏÅóÎÏıÎèò@@¯@¯åjÃb?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Úò@@į@įÃj b?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Úò@Äú¯Äú¯ j(b?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Úòů@¯HHö˘àÍ<IJˇˇˇˇˇˇˇˇˇˇÃÃˇˇˇˇôôˇˇˇˇffˇˇˇˇ33ˇˇˇˇˇˇÃÃˇˇˇˇÃÃÃÃˇˇÃÃôô    ˇˇÃÃff
  12638. ˇˇÃÃ33 ˇˇÃà ˇˇôôˇˇ
  12639. ˇˇôôÃÃˇˇôôôôˇˇôôffˇˇôô33ˇˇôôˇˇffˇˇˇˇffÃÃˇˇffôôˇˇffffˇˇff33ˇˇffˇˇ33ˇˇˇˇ33ÃÃˇˇ33ôôˇˇ33ffˇˇ3333ˇˇ33ˇˇˇˇˇˇÃàˇˇôô!ˇˇff"ˇˇ33#ˇˇ$ÃÃˇˇˇˇ%ÃÃˇˇÃÃ&ÃÃˇˇôô'ÃÃˇˇff(ÃÃˇˇ33)ÃÃˇˇ*ÃÃÃÃˇˇ+ÃÃÃÃÃÃ,ÃÃÃÃôô-ÃÃÃÃff.ÃÃÃÃ33/ÃÃÃÃ0ÃÃôôˇˇ1ÃÃôôÃÃ2ÃÃôôôô3ÃÃôôff4ÃÃôô335ÃÃôô6ÃÃffˇˇ7ÃÃffÃÃ8ÃÃffôô9ÃÃffff:ÃÃff33;ÃÃff<ÃÃ33ˇˇ=ÃÃ33ÃÃ>ÃÃ33ôô?ÃÃ33ff@ÃÃ3333AÃÃ33BÃÃˇˇCÃÃÃÃDÃÃôôEÃÃffFÃÃ33GÃÃHôôˇˇˇˇIôôˇˇÃÃJôôˇˇôôKôôˇˇffLôôˇˇ33MôôˇˇNôôÃÃˇˇOôôÃÃÃÃPôôÃÃôôQôôÃÃffRôôÃÃ33SôôÃÃTôôôôˇˇUôôôôÃÃVôôôôôôWôôôôffXôôôô33YôôôôZôôffˇˇ[ôôffÃÃ\ôôffôô]ôôffff^ôôff33_ôôff`ôô33ˇˇaôô33ÃÃbôô33ôôcôô33ffdôô3333eôô33fôôˇˇgôôÃÃhôôôôiôôffjôô33kôôlffˇˇˇˇmffˇˇÃÃnffˇˇôôoffˇˇffpffˇˇ33qffˇˇrffÃÃˇˇsffÃÃÃÃtffÃÃôôuffÃÃffvffÃÃ33wffÃÃxffôôˇˇyffôôÃÃzffôôôô{ffôôff|ffôô33}ffôô~ffffˇˇffffÃÃÄffffôôÅffffffÇffff33ÉffffÑff33ˇˇÖff33ÃÃÜff33ôôáff33ffàff3333âff33äffˇˇãffÃÃåffôôçfffféff33èffê33ˇˇˇˇë33ˇˇÃÃí33ˇˇôôì33ˇˇffî33ˇˇ33ï33ˇˇñ33ÃÃˇˇó33ÃÃÃÃò33ÃÃôôô33ÃÃffö33ÃÃ33õ33ÃÃú33ôôˇˇù33ôôÃÃû33ôôôôü33ôôff†33ôô33°33ôô¢33ffˇˇ£33ffÃç33ffôô•33ffff¶33ff33ß33ff®3333ˇˇ©3333ÃÙ3333ôô´3333ff¨333333≠3333Æ33ˇˇØ33ÃÃ∞33ôô±33ff≤3333≥33¥ˇˇˇˇµˇˇÃÃ∂ˇˇôô∑ˇˇff∏ˇˇ33πˇˇ∫ÃÃˇˇªÃÃÃúÃÃôôΩÃÃffæÃÃ33øÃÿôôˇˇ¡ôôÃìôôôô√ôôffƒôô33≈ôôΔffˇˇ«ffÃûffôô…ffff ff33ÀffÃ33ˇˇÕ33ÃÃŒ33ôôœ33ff–3333—33“ˇˇ”ÃÑôô’ff÷33◊ÿˇˇˇŸ˘`˘`˘`⁄Ú–Ú–Ú–€Ï@Ï@Ï@‹Â∞Â∞Â∞›fl fl fl fiÿêÿêÿêfl“““‡ÀpÀpÀp·ƒ‡ƒ‡ƒ‡‚æPæPæP„∑¿∑¿∑¿‰±0±0±0™†™†™†Ê§§§ÁùÄùÄùÄËñññÈê`ê`ê`Íâ–â–â–ÎÉ@É@É@Ï|∞|∞|∞Ìv v v ÓoêoêoêÔiiibpbpbpÒ[‡[‡[‡ÚUPUPUPÛN¿N¿N¿ÙH0H0H0ıA†A†A†ˆ;;;˜4Ä4Ä4į---˘'`'`'`˙ – – –˚@@@¸∞∞∞˝
  12640.  
  12641.  
  12642.  ˛êêê@¯åjÃb'"ÎÓˇ¬ˇˇÌˇ‚ÎÅóÏÎıÏè"ÎÓˇ¬ˇˇÌˇ‚ÏÅóÎÏıÎè&ÏÓˇ˜˛ˇœˇˇÌˇ‚ÎÅóÎÎıÎè5ÎÓˇ¯ˇ˛ˇÏˇÊˇˇÌˇ‚ÎπÏÎÏÎÅ„ÏÎıÏèMÏÓˇ˘ˇ˚ˇˇ˛ˇˇˇˇˇ˝ˇˇ˝ˇˇˇÌˇˇÌˇ‚Î∫ν΀ÎãÎÎıÎèpÎÓˇ˘ˇ˙ˇ ˇˇˇˇˇ˝ˇˇˇˇˇÌˇˇÌˇ‚Ï∫Ï˝ÎÎÎÎÏÎÎÎÎÎνÎÏÎÏÎÎÎÏÎÎÏÎåÎÏıÎèrÎÓˇ˘ˇˇ˛ˇˇ˝ ˇˇˇˇˇˇ˝ˇˇ˛ˇˇÌˇˇÌˇ‚Î∫νÏÎÎÏÏÎÏÎÏÎÏÏ˝ÎÏÎÏÎÏÏÎÎãÏÎıÏèmÎÓˇ˜˝ˇ˛ˇ    ˇˇˇˇˇ˛˛ˇˇ˛ˇˇÏˇˇÌˇ‚Ï∫Ï˝ ÎÎÏÎÏÎÏ˝Î˝Î˛ÎÎÎÎÎÎÏãÎÏıÎèQÏÓˇŸˇÎˇˇÌˇ‚ÎπÎÏÎÎÎÏÎÎÎÏÎθ˛ÎÎβÎÎÏÎåÎÎıÎè&ÎÓˇ⁄ˇÍˇˇÌˇ‚ÎÅóÏÎıÏè"ÏÓˇ¬ˇˇÌˇ‚ÎÅóÎÎıÎè"ÎÓˇ¬ˇˇÌˇ‚ÏÅóÎÏıÎè"ÎÓˇ¬ˇˇÌˇ‚ÎÅóÏÎıÏèÎÓøˇÌˇ‚ÏÅóÎÏıÎèÏÓˇ¬ˇˇÌˇ‚ÎÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏÎÎıÎè"ÎÓˇ¬ˇˇÌˇ‚ÎÅóÏÎıÏè"ÏÓˇ¬ˇˇÌˇ‚ÎÅóÎÎıÎè"ÎÓˇ¬ˇˇÌˇ‚ÏÅóÎÏıÎè)ÎÓˇ¯˚ˇˇ”ˇˇÌˇ‚ÎÅóÏÎıÏè0ÎÓˇ¯ˇ˝ˇˇ”ˇˇÌˇ‚Ï®ÎÅÒÎÏıÎè@ÏÓˇ¯ˇ˛ˇˇˇ”ˇˇÌˇ‚ÎπÎÏ˛Î˜ÎÎθÏÅ˘ÎÎıÎè:ÎÓˇ¯˚ˇˇ”ˇˇÌˇ‚Î∫ÎÏÏˆÏ˘ÎÅ˘ÏÎıÏèHÏÓˇ¯ˇ˛ˇˇˇ”ˇˇÌˇ‚Î∏ϸÎβÎÏÎÎÏ˛ÏÎÅ˙ÎÎıÎèGÎÓˇ¯ˇ˛ˇˇˇ”ˇˇÌˇ‚Ï∏νÎÎÎÎÏÎÏÎÎÎůÎÏıÎè>ÎÓˇ¬ˇˇÌˇ‚Î∏βÎÎÏÏβ
  12643. ÎÏÏÏÎÏÏÎÅ˘ÏÎıÏè=ÎÓˇ¬ˇˇÌˇ‚Ïπ˛ÎÎÎÏ˛ÎÏ˛    ÏÎÎÎÎůÎÏıÎè*ÏÓˇ¬ˇˇÌˇ‚αÎÎÎÅÏÎÎıÎè'ÎÓˇ¬ˇˇÌˇ‚Î∞ÎÏÅÍÏÎıÏèÏÓøˇÌˇ‚ÎÅóÎÎıÎè"ÎÓˇ¬ˇˇÌˇ‚ÏÅóÎÏıÎèÎÓˇ¬ˇˇÌˇ‚ÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏlÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎıÏèÎÓˇ¬ˇˇÌˇ‚Ï˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏıÎèÏÓˇ¬ˇˇÌˇÅÅÈÎèÎӡ͡⁄ˇˇÌˇÅÅÈÏè'ÏÓˇ˜˛ˇˇ˚ˇˇŸˇˇÌˇÅÅÈÎè(ÎÓˇ¯ˇ˝ˇ˙ˇŸˇˇÓˇˇÅÅÈÎè/ÎÓˇ¯ˇˇˇˇˇˇˇˇ‹ˇˇÓˇÅÅËÏè.ÎÓˇ˜
  12644. ˇˇˇˇˇˇˇ˛ˇ›ˇˇÚ¸ˇÅÅËÎè8ÏÓˇ˘ˇ˛˛ˇ˛ˇ˛ˇ⁄ÔˇÅÈ˘ˇÔÔ˛Ô˛ÔÔˆˇõÎè?ÎÓˇ¯˛ˇˇ¸ˇˇˇˇ‹ˇˇÅŸˇ˚‹
  12645. ÔÔÔÔÔÔÔ¯‹ˇõÏè6ÏÓˇÔˇ’ˇˇÅŸˇ˝‹Ô˛Ô˛Ô˛Ô˛Ô˙‹ˇõÎè6ÎÓˇÒˇˇ‘ˇˇÅŸˇ˝‹˛Ô˛Ô˛Ô˛Ô˛Ô˚‹ˇõÎè4ÎÓˇ¬ˇˇÅŸˇ˛‹ÔÔÔÔÔÔÔÔÔÔ˚‹ˇõÏè5ÎÓˇ¬ˇˇÅŸˇ‹‹Ô˛Ô˛Ô˛Ô˛Ô˛Ô¸‹ˇõÎè0ÏÓøˇÅŸ
  12646. ˇ‹ÔÁÁËËÔÔ˛Ô˛Ô˛Ô˛Ô˝‹ˇõÎè6ÎÓˇ¬ˇˇÅŸˇˇÁ˛ËÁ˛ËÁËÔÔÔÔÔÔÔ˝‹ˇõÏè5ÏÓˇ¬ˇˇÅŸˇˇËËÁÁËËÁÁËËÁÔ˛Ô˛Ô˛Ô˝‹ˇõÎè6ÎÓˇ¬ˇˇÅŸˇˇÁÁËËÁÁËËÁÁËËÁÔ‡‡ÔÔ˛ÔÔ˝‹ˇõÎè1ÎÓˇ¬ˇˇÅŸˇˇËËÁ˛ËÁˢ˝˙‡ÔÔ˛‹ˇõÏè3ÎÓˇ¬ˇˇÅŸ    ˇËÁÁËËÁÁËË˚˛‡fl˛‡flÔÔ˛‹ˇõÎè:ÏÓˇÒΔˇˇÅ¡ˆˇˇËËÁÁˡ˘fl˛‡fl˛‡Ô˛‹ˇõÎè5ÎÓˇ˘ÏÎϸϔˇˇÅÂ˚ˇ˚ˇˇÁ˛ËÁˆ¯‡˛‹ˇõÏè:ÏÓˇ¯Î˚ΔˇˇÅ˜ˇˇˇËËÁÁˈ˛‡fl˛‡fl‡˛‹ˇõÎèOÎÓˇ˘
  12647. ÎÎÎÏÎÎ’Åˇ⁄ˇ˛ˇˇÁÁËËı‡fl˛‡fl‡‡˜˜‹‹ˇ˚ˇˇ˚ˇˇ¯ˇˇ˛ˇˇªÎèMÎÓˇ˘    ÏÎÏÎÏΑˇˇÅ¸ˇ˙ˇˇËËÁ˜ı˙‡˛˜‹‹ˇ˚ˇˇ˚ˇˇ¯ˇˇÛˇˇΔÏè\ÎÓˇ˙βÎÏ˛ÎÏÎ’ˇˇÅ¡ˆ˛ˇÁËÛfl˛‡fl‡˛˜¯‹ˇ˚ˇˇ˛ˇ¸ˇ˝ˇ˝ˇ¸ˇ˙ˇ«ÎèTÏÓˇ˙
  12648. ÏÎÎÎÏΑˇˇÅŸ˛ˇËÁÛ‡‡fl‡‡¸˜‹ˇ˚ˇˇ˝ˇ˛ˇˇˇ˝ˇ˜ˇ˝ˇΔÎèFÎÓˇ¬ˇˇ÷‚ˇ£˝ˇÚ¸‡¸˜‹ˇ˚ˇˇ˝ˇ˝ˇˇˇ˝ˇ¸ˇ˛ˇˇ˛ˇˇΔÏè\ÏÓˇ¬ˇˇ÷ˇˇ„˛‰„˛‰„˛‰ˇˇÙ‹ˇˇ£˝ˇ˜Û‡‡fl‡˛˜¯˜˜‹ˇ˚ˇˇ˝ˇ¸ˇ˝ˇ˝ˇ˚ˇ˙ˇ«Îè=ÎÓˇ¬ˇˇ÷ˇˇ‰‰„˛‰¸ˇ‰ˇÛ‹ˇˇ£˝ˇÔÙfl˛‡˙˜ˇ„ˇˇªÎè:ÎÓøˇ÷ˇˇ˛‰„‰ˇˇ„‰‰¸ˇı‹ˇˇ£˝ˇÔÔˆ‡‡˜˜ˇ„ˇˇªÏèDÎÓˇ¬ˇˇ÷˛ˇ‰„˛ˇ„˛‰„‰‰‹ˇˆ‹˛ˇ£˝ˇ˛Ô¯˜˜¯˛˜¯˛˜¯‹ˇõÎèAÏÓˇ¬ˇˇ÷˛ˇ‰ˇˇ„˛‰„˛‰„‹ˇˇ˜‹˛ˇ£¸ˇÔ˛Ô˛ÔÔÔı˜‹ˇõÎèBÎÓˇ¬ˇˇ÷˛ˇ‰‰„˛‰„‰ˇˇ‹‹ˇˇ¯‹˛ˇ£¸ˇ ÔÔÔÔÔÔı˜‹ˇõÏèòů@įHHö˙‹Í=IJˇˇˇˇˇˇˇˇˇˇÃÃˇˇˇˇôôˇˇˇˇffˇˇˇˇ33ˇˇˇˇˇˇÃÃˇˇˇˇÃÃÃÃˇˇÃÃôô    ˇˇÃÃff
  12649. ˇˇÃÃ33 ˇˇÃà ˇˇôôˇˇ
  12650. ˇˇôôÃÃˇˇôôôôˇˇôôffˇˇôô33ˇˇôôˇˇffˇˇˇˇffÃÃˇˇffôôˇˇffffˇˇff33ˇˇffˇˇ33ˇˇˇˇ33ÃÃˇˇ33ôôˇˇ33ffˇˇ3333ˇˇ33ˇˇˇˇˇˇÃàˇˇôô!ˇˇff"ˇˇ33#ˇˇ$ÃÃˇˇˇˇ%ÃÃˇˇÃÃ&ÃÃˇˇôô'ÃÃˇˇff(ÃÃˇˇ33)ÃÃˇˇ*ÃÃÃÃˇˇ+ÃÃÃÃÃÃ,ÃÃÃÃôô-ÃÃÃÃff.ÃÃÃÃ33/ÃÃÃÃ0ÃÃôôˇˇ1ÃÃôôÃÃ2ÃÃôôôô3ÃÃôôff4ÃÃôô335ÃÃôô6ÃÃffˇˇ7ÃÃffÃÃ8ÃÃffôô9ÃÃffff:ÃÃff33;ÃÃff<ÃÃ33ˇˇ=ÃÃ33ÃÃ>ÃÃ33ôô?ÃÃ33ff@ÃÃ3333AÃÃ33BÃÃˇˇCÃÃÃÃDÃÃôôEÃÃffFÃÃ33GÃÃHôôˇˇˇˇIôôˇˇÃÃJôôˇˇôôKôôˇˇffLôôˇˇ33MôôˇˇNôôÃÃˇˇOôôÃÃÃÃPôôÃÃôôQôôÃÃffRôôÃÃ33SôôÃÃTôôôôˇˇUôôôôÃÃVôôôôôôWôôôôffXôôôô33YôôôôZôôffˇˇ[ôôffÃÃ\ôôffôô]ôôffff^ôôff33_ôôff`ôô33ˇˇaôô33ÃÃbôô33ôôcôô33ffdôô3333eôô33fôôˇˇgôôÃÃhôôôôiôôffjôô33kôôlffˇˇˇˇmffˇˇÃÃnffˇˇôôoffˇˇffpffˇˇ33qffˇˇrffÃÃˇˇsffÃÃÃÃtffÃÃôôuffÃÃffvffÃÃ33wffÃÃxffôôˇˇyffôôÃÃzffôôôô{ffôôff|ffôô33}ffôô~ffffˇˇffffÃÃÄffffôôÅffffffÇffff33ÉffffÑff33ˇˇÖff33ÃÃÜff33ôôáff33ffàff3333âff33äffˇˇãffÃÃåffôôçfffféff33èffê33ˇˇˇˇë33ˇˇÃÃí33ˇˇôôì33ˇˇffî33ˇˇ33ï33ˇˇñ33ÃÃˇˇó33ÃÃÃÃò33ÃÃôôô33ÃÃffö33ÃÃ33õ33ÃÃú33ôôˇˇù33ôôÃÃû33ôôôôü33ôôff†33ôô33°33ôô¢33ffˇˇ£33ffÃç33ffôô•33ffff¶33ff33ß33ff®3333ˇˇ©3333ÃÙ3333ôô´3333ff¨333333≠3333Æ33ˇˇØ33ÃÃ∞33ôô±33ff≤3333≥33¥ˇˇˇˇµˇˇÃÃ∂ˇˇôô∑ˇˇff∏ˇˇ33πˇˇ∫ÃÃˇˇªÃÃÃúÃÃôôΩÃÃffæÃÃ33øÃÿôôˇˇ¡ôôÃìôôôô√ôôffƒôô33≈ôôΔffˇˇ«ffÃûffôô…ffff ff33ÀffÃ33ˇˇÕ33ÃÃŒ33ôôœ33ff–3333—33“ˇˇ”ÃÑôô’ff÷33◊ÿˇˇˇŸ˘`˘`˘`⁄Ú–Ú–Ú–€Ï@Ï@Ï@‹Â∞Â∞Â∞›fl fl fl fiÿêÿêÿêfl“““‡ÀpÀpÀp·ƒ‡ƒ‡ƒ‡‚æPæPæP„∑¿∑¿∑¿‰±0±0±0™†™†™†Ê§§§ÁùÄùÄùÄËñññÈê`ê`ê`Íâ–â–â–ÎÉ@É@É@Ï|∞|∞|∞Ìv v v ÓoêoêoêÔiiibpbpbpÒ[‡[‡[‡ÚUPUPUPÛN¿N¿N¿ÙH0H0H0ıA†A†A†ˆ;;;˜4Ä4Ä4į---˘'`'`'`˙ – – –˚@@@¸∞∞∞˝
  12651.  
  12652.  
  12653.  ˛êêê@įÃj b'sÏÓˇ¬ˇˇ÷˛ˇ‰‰„˛‰„˝ˇ˛‹˛ˇ˙‹˛ˇ£¸ˇÔ˛Ô˛ÔÔ˜˜¯˛˜¯˛˜¯˜˜‹ˇ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏÎÎ≈Îè>ÎÓˇ¬ˇˇ÷˛ˇ„˛‰˚ˇ˝‹˛ˇ˙‹˛ˇ£¸ˇ˛Ô˛ÔÔÔÛ˜‹ˇÿÏÎΔÎèEÎÓˇ‚ÎÏ„ˇˇ‚˛ˇ¯˛ˇ˜ˇ¸‹ˇˇ˙‹˛ˇ£˚ˇÔÔÔÔÛ˜‹‹ˇÿÎÏΔÏèUÎÓˇ˘ÎÏ˛Îηˇˇ‚˙ˇ¸˛ˇ˜ˇ¸‹ˇˇ˚‹˝ˇ£˙ˇÔ˛Ô¯˛˜¯˛˜¯˛˜¯˜˜˛‹ˇÿÏÎΔÎè>ÏÓˇ˙ÏÎÎη÷ˇ˛ˇ˜ˇÙ‹˝ˇ£˙ˇ˜ÔÔÚ˜¸ˇÿÎÎΔÎèUÎÓˇ¯Î˛ ÎÎÏÏÎÏÎÎÏÎÏÎÏÎÎÎÏÎÏÏÏÎˇˇ‚¯ˇ˛ˇˇ˛˜ˇı‹˝ˇõάÎÏΔÏè[ÏÓˇ¯Î˝ ÎÎÏÎÎÏÎβÎÏÎβ˛ÎÏÎÔˇˇ‚˝ˇ˘ˇ¸ˇˇ˛˛ˇ¸ˇˇ˚‹˝ˇõάÎÎΔÎèaÎÓˇ¯Ï˛ÏÎÎÎÏÎÎÏÎÎÏÎÎβÎÏÎÏˇˇ÷ˇÎ˛ˇˇÙˇˇ˝ˇ˛ˇ˚ˇõϬÏÎΔÎè}ÎÓˇ˘ÏÎÏÎÏÎÏÏÎÎÏÎÏÎβÎÎÏÔˇˇ÷ˇÎˇˇ˛ˇˇ˝ˇˇ˛ˇ˛¸ˇ¸˚ˇˇˇÎˇˇ˛ˇˇ÷ΘÏÎ˚Ï’ÎÏΔÏè]ÎÓˇÊÎχˇˇ÷ˇˇ˝˛ˇˇ˝ˇˇ˝ˇˇ¸ˇ˙ˇˇÔˇˇÍˇˇÛˇˇ·Ï˘ÎÎθΒÏÎΔÎèqÏÓˇÂÎflˇˇ÷ˇˇˇˇ˝ˇ˝ˇˇ˚ˇ¸ˇ˙ˇˇ˙ˇ˛ˇˆˇ˘ˇ˝˝ˇ˝ˇ¸ˇ˙ˇ‚΢Î˚
  12654. ÎÎÎÏÎÎÏ‹ÎÎΔÎèiÎÓˇ¬ˇˇ÷˚ˇ˘ˇˇ˙ˇ˛˝ˇ˙ˇˇˇˇıˇ˝ˇ˝ˇ˚ˇˇˇ˝ˇ˜ˇ˝ˇ·Î˘Ï¸
  12655. ÏÎÏÏÎÏ€ÎÏΔÏèmÏÓøˇ÷˜ˇ˝ˇ˘ˇ˛˝ˇ˙ˇˇˇˇˇˇ˚ˇ˛˚ˇ˝ˇ˚ˇˇˇ˝ˇ¸ˇ˛ˇˇ˛ˇˇ·Î˘Î˛ ÎÎÏÎÎÎ΀ÎÎΔÎèkÎÓˇ¬ˇˇ÷¯ˇ˛ˇˇ¯ˇˇ˝ˇ˙ˇˇˇˇıˇˇˇ˝ˇˇˇ˚ˇ˛˝ˇ˝ˇ˚ˇ˙ˇ‚ϯÎÎÏ˛    ÏÎÎÎÎ΀ÏÎΔÎè2ÎÓˇ¬ˇˇ÷˘ˇ˛ˇˇˆˇ˝ˇ»ˇˇ÷άÎÏΔÏè2ÎÓˇ¬ˇˇ÷˙ˇ˛ˇˇˆ˛ˇ˝ˇ»ˇˇ÷ϬÏÎΔÎèhÏÓˇ¬ˇˇ÷˚ˇ˛ˇı˛ˇ˝ˇõÎÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎΔÎè.ÎÓˇ¬ˇˇ÷˚ˇ˛ˇÙˇˇ˛ˇõάÎÏΔÏè8ÏÓˇ¯Î˜ÎΟˇˇ÷¸ˇ˛ˇÛˇˇ˛ˇõάÎÎΔÎè{ÎÓˇ˘ÎβÎθί΄ˇˇ÷˝ˇ˛ˇˇÒˇ˛ˇÎÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛Î’Ï¬ÏÎΔÎèMÎÓˇ˘ ÏÏÎÏÎÏÎÏÏÏÎÏÏÎÎÏÎÏÎÏÎÏΡˇ÷˛ˇË˛ˇ»ÏÎ÷άÎÏΔÏèKÎÓˇ˘ÎÏβÎÎÏÎÎÏÎÏÎÏ˛ÎÏÎÈˇˇ÷˝ˇÈ˛ˇ»ÎÏ÷ϬÏÎΔÎè\ÏÓˇ˙Ï˛ÏÎÎÎÎÎÎÎÎÎθÏÎΡˇ÷ˆˇÔˇˇ»ÎÎ÷΢ÎÏ˛ÎÎÍ΢ÎÎΔÎèUÎÓˇ˙ββÎÎÏÏÎÏÎÏβÎÏÎÏÎÏÎ͡ˇ÷‚ˇ»ÏÎ÷ΘÏÔÎÈÏ˘ÎÏΔÏèXÏÓˇ¬ˇˇŒÎ≤ÎÎ÷ΘÎÏÎÎÏÎÏÎÏ˛ÎÏÎÎÏÎβÎÏβÎβÎÏÎÎϸÎÎΔÎèWÎÓˇ¬ˇˇŒÎ≤ÎÏ÷ϘÎÎÏ˛ÎÎÏÎβÎÏ˛ÎÏ˝ÎÎÎÎÎÏÎÏ˛Î˝ÏÎΔÎèYÎÓˇ¬ˇˇŒÏÒÎ√ÏÎ÷ΘÏÎÎÏÏÎÏÎÎβνÏÏÏÏÎÎÏÎ˙ÎÏΔÏèaÎÓˇ¬ˇˇŒÎ˜ÎÎÏÎÎ΃ÎÏ÷ϘÎβÎÎÏ˛ÎβÎÏ˝ÎÎÎÏβ˛Î˛Î˝ÏÎΔÎè*ÏÓøˇŒÎ¯Î˛ÎάÎÎ÷άÎÎΔÎè4ÎÓˇ¬ˇˇŒÏ˘Î˚ÏÏ˛ÏÎ…ÏÎ÷άÎÏΔÏè5ÏÓˇ¬ˇˇŒÎ˘Î¸ÏÎÎÎÎÏ…ÎÎ÷άÎÎΔÎè6ÎÓˇ¬ˇˇŒÎ˘Ï˛ÏÎÎÏ˛ÏλÎÏ÷ϬÏÎΔÎèpÎÓˇ¬ˇˇŒÏ¯ÏÎÏÎβΫÏÎ÷AÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏΔÏè)ÎÓˇ¬ˇˇŒÎÓÎΔÎÏ÷ϬÏÎΔÎè/ÏÓˇ˘˛ÎÏŒˇˇŒÎÓÎΔÎÎ÷άÎÎΔÎè1ÎÓˇ˙νÏ⁄ϘˇˇŒÏ≤ÏÎ÷άÎÏΔÏè†ÏÓˇ˙Ï˝    ÎÎÎÏÎβÎÎÎνÎÏÎÏÎÎÎÏÎÏÎίˇˇŒ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏÎÎ÷άÎÎΔÎèSÎÓˇ˙ν
  12656. ÎÎÎÏÎÎÎÏ˛Î˝ÏÎÏÎÎÏÎÏΘˇˇŒÎ≤ÎÏ÷ϬÏÎΔÎè^ÎÓˇ˙ν ÏÎÏÏÎÏÏ˛Ï˝Î˛ÎÏÏÎÏÎϘˇˇŒÏ≤ÏÎ÷ΘϯÏÏŸÎÏΔÏèeÎÓˇ˘ÎÏÎβ
  12657. ÎÎÎÎÏ˛Î¸˛ÎÎβÎÎÏÎÏ˛Ï¯ˇˇŒÎ≤ÎÏ÷ϯÎÏÎθί΄ÏÎΔÎèGÏÓˇ¬ˇˇŒÎ≤ÎÎ÷ίÏÎÏ˛ÎÏÎβΠÎÏÎÎÏÎβÎÎÎÎΔÎèRÎÓˇ¬ˇˇŒÏ˘Î˝ÏÛΜÏÎ÷ίÎÏÎÏÏÎÏÏÎÏÎÏÎÏÎÏÎÏÈÎÏΔÏèPÏÓˇ¬ˇˇŒÎ˘ÎÎÎοÎÎ÷΢βÎÎÎÏÎÎÏÎÏÎϸÎÎÎÎÎΔÎècÎÓøˇŒÎ˘ÏÎÏÎÎÏÎÏÎÎÏÎÏ˛Î˛ÎÏÎÿÎÏ÷Ï˘Î˛ÎÏÎÎÎÏÎÏÎβÎÎÏ˛ÎÏÍÏÎΔÎèFÎÓˇ¬ˇˇŒÏ˘ÎÎÏÏÎÏÎÏÏÎÏÎÎÏÎÎÏÿÏÎ÷άÎÏΔÏèFÎÓˇ¬ˇˇŒÎ˘ÏÎÎÎÎÎÎÎÎÎÏÎÏÎÎÿÎÏ÷ϬÏÎΔÎèEÏÓˇ¬ˇˇŒÎ˘ÎÏβββÎÎÎβÎÿÎÎ÷άÎÎΔÎè1ÎÓˇ¬ˇˇŒÏÓÏ˛ÏÙÏÿÏÎ÷άÎÏΔÏèrÏÓˇÁΛˇˇŒÎÓÎ˛Î˜ÏÎÎ◊ÎÎ÷ÎÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎΔÎè7ÎÓˇ˘ÎÏ˛ÎˆÎÏθωˇˇŒÎ≤ÎÏ÷ϬÏÎΔÎè6ÎÓˇ˙ÎÏÏıÎ˙ΉˇˇŒÏ≤ÏÎ÷άÎÏΔÏè@ÎÓˇ¯Ï¸ÎβÎÏ˛    ÏÎÎÏΡˇŒÎ≤ÎÏ÷ϬÏÎΔÎèäÏÓˇ¯Î˝ÎÎÎβÎÎÏÎÎ΄ˇˇŒ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏÎÎ÷άÎÎΔÎè@ÎÓˇ¯Î˛ÎÎÏÏν    ÏÎÏÎÏÎÏΉˇˇŒÏ≤ÏÎ÷άÎÏΔÏèEÏÓˇ˘˛ÎÎÎÏ˛ÎÏ˝ÎÎÎÎ΄ˇˇŒÎ≤ÎÎ÷Î¯Ï˛ÎœÎÎΔÎè9ÎÓˇÒÎÎÎ◊ˇˇŒÎ≤ÎÏ÷Ï˘Î˝Î€Î˜ÏÎΔÎè]ÎÓˇÎÏ’ˇˇŒÏ—΄ÏÎ÷Î˘Ï˝ÎÏÎÎÏÎÏÎÏÏνÏÎÏÎÏÎÏÎÏÎÏίÎÏΔÏèmÎÓˇ¬ˇˇŒÎ˘ÏÎÏÎÎÁβÎÎθÎÍÎÏ÷Ï˘Î˝
  12658. ÎÎÎÎÏÎÏ˛ÎÏνÎÎÎÎÎÎÎÎΘÏÎΔÎèfÏÓˇ¬ˇˇŒÎ¯ÎÎ‰Ï˝Î˙ÎÍÎÎ÷΢ν ÏÎÎÎÎÎÎ˛Î˝Ï˛ÏÎÎÏÎÏΘÎÎΔÎèÄÎÓøˇŒÏ¯ÏÎÏÎÎÏÏÏν ÏÎÎÏÏÏÎÎÏ˛    ÏÏÎÏÎÎÏÎ÷ίÎÏÎÏÎÏÏÎÎÏÎϸÏÎÏÏβÎÏÎÏÎ˛Î¯ÎÏΔÏèPÏÌ¿ˇŒÎ¯ ÎÎÏÎÎÏÎÎÎÏÎÏÎÎÎÏνÏÎÎÎÎÏÈÎÎ÷άÎÎΔÎèNÎÅ˘Î¯ÎβÎÏ˛ÏÎνÎÎÎÏβÎβÎÎÏÎÏ˛ÎÍÎÏ÷ϬÏÎΔÎèKÎÅ˘Ï¯Ï˝
  12659. ÎÏÎÏÎθβÎÏÏ˛Ï˝ÎÎÏÎÎÈÏÎ÷άÎÏΔÏè"ÎÅ˘Î‰Î–ÎÏ÷ϬÏÎΔÎèòůÄú¯HHö˘àÍ>IJˇˇˇˇˇˇˇˇˇˇÃÃˇˇˇˇôôˇˇˇˇffˇˇˇˇ33ˇˇˇˇˇˇÃÃˇˇˇˇÃÃÃÃˇˇÃÃôô    ˇˇÃÃff
  12660. ˇˇÃÃ33 ˇˇÃà ˇˇôôˇˇ
  12661. ˇˇôôÃÃˇˇôôôôˇˇôôffˇˇôô33ˇˇôôˇˇffˇˇˇˇffÃÃˇˇffôôˇˇffffˇˇff33ˇˇffˇˇ33ˇˇˇˇ33ÃÃˇˇ33ôôˇˇ33ffˇˇ3333ˇˇ33ˇˇˇˇˇˇÃàˇˇôô!ˇˇff"ˇˇ33#ˇˇ$ÃÃˇˇˇˇ%ÃÃˇˇÃÃ&ÃÃˇˇôô'ÃÃˇˇff(ÃÃˇˇ33)ÃÃˇˇ*ÃÃÃÃˇˇ+ÃÃÃÃÃÃ,ÃÃÃÃôô-ÃÃÃÃff.ÃÃÃÃ33/ÃÃÃÃ0ÃÃôôˇˇ1ÃÃôôÃÃ2ÃÃôôôô3ÃÃôôff4ÃÃôô335ÃÃôô6ÃÃffˇˇ7ÃÃffÃÃ8ÃÃffôô9ÃÃffff:ÃÃff33;ÃÃff<ÃÃ33ˇˇ=ÃÃ33ÃÃ>ÃÃ33ôô?ÃÃ33ff@ÃÃ3333AÃÃ33BÃÃˇˇCÃÃÃÃDÃÃôôEÃÃffFÃÃ33GÃÃHôôˇˇˇˇIôôˇˇÃÃJôôˇˇôôKôôˇˇffLôôˇˇ33MôôˇˇNôôÃÃˇˇOôôÃÃÃÃPôôÃÃôôQôôÃÃffRôôÃÃ33SôôÃÃTôôôôˇˇUôôôôÃÃVôôôôôôWôôôôffXôôôô33YôôôôZôôffˇˇ[ôôffÃÃ\ôôffôô]ôôffff^ôôff33_ôôff`ôô33ˇˇaôô33ÃÃbôô33ôôcôô33ffdôô3333eôô33fôôˇˇgôôÃÃhôôôôiôôffjôô33kôôlffˇˇˇˇmffˇˇÃÃnffˇˇôôoffˇˇffpffˇˇ33qffˇˇrffÃÃˇˇsffÃÃÃÃtffÃÃôôuffÃÃffvffÃÃ33wffÃÃxffôôˇˇyffôôÃÃzffôôôô{ffôôff|ffôô33}ffôô~ffffˇˇffffÃÃÄffffôôÅffffffÇffff33ÉffffÑff33ˇˇÖff33ÃÃÜff33ôôáff33ffàff3333âff33äffˇˇãffÃÃåffôôçfffféff33èffê33ˇˇˇˇë33ˇˇÃÃí33ˇˇôôì33ˇˇffî33ˇˇ33ï33ˇˇñ33ÃÃˇˇó33ÃÃÃÃò33ÃÃôôô33ÃÃffö33ÃÃ33õ33ÃÃú33ôôˇˇù33ôôÃÃû33ôôôôü33ôôff†33ôô33°33ôô¢33ffˇˇ£33ffÃç33ffôô•33ffff¶33ff33ß33ff®3333ˇˇ©3333ÃÙ3333ôô´3333ff¨333333≠3333Æ33ˇˇØ33ÃÃ∞33ôô±33ff≤3333≥33¥ˇˇˇˇµˇˇÃÃ∂ˇˇôô∑ˇˇff∏ˇˇ33πˇˇ∫ÃÃˇˇªÃÃÃúÃÃôôΩÃÃffæÃÃ33øÃÿôôˇˇ¡ôôÃìôôôô√ôôffƒôô33≈ôôΔffˇˇ«ffÃûffôô…ffff ff33ÀffÃ33ˇˇÕ33ÃÃŒ33ôôœ33ff–3333—33“ˇˇ”ÃÑôô’ff÷33◊ÿˇˇˇŸ˘`˘`˘`⁄Ú–Ú–Ú–€Ï@Ï@Ï@‹Â∞Â∞Â∞›fl fl fl fiÿêÿêÿêfl“““‡ÀpÀpÀp·ƒ‡ƒ‡ƒ‡‚æPæPæP„∑¿∑¿∑¿‰±0±0±0™†™†™†Ê§§§ÁùÄùÄùÄËñññÈê`ê`ê`Íâ–â–â–ÎÉ@É@É@Ï|∞|∞|∞Ìv v v ÓoêoêoêÔiiibpbpbpÒ[‡[‡[‡ÚUPUPUPÛN¿N¿N¿ÙH0H0H0ıA†A†A†ˆ;;;˜4Ä4Ä4į---˘'`'`'`˙ – – –˚@@@¸∞∞∞˝
  12662.  
  12663.  
  12664.  ˛êêêÄú¯ j(b']ÏÅ˘Î‰Î–ÎÎ÷ÎÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎΔÎèÎÅ˘Ï≤ÏÎ÷άÎÏΔÏèÏÅ˘Î≤ÎÎ÷άÎÎΔÎèÎÅ˘Î≤ÎÏ÷ϬÏÎΔÎèjÎÅ˘QÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎ÷άÎÏΔÏè"ÎÅ˘Î≤ÎÏ÷ÏÁΛÏÎΔÎè0ÏÅ˘Î≤ÎÎ÷΢ÎÏ˛ÎˆÎÏθωÎÎΔÎè/ÎÅ˘Ï≤ÏÎ÷Î˙ÎÏÏıÎ˙ΉÎÏΔÏè9ÏÅ˘Î≤ÎÎ÷ίϸÎβÎÏ˛    ÏÎÎÏÎÂÎÎΔÎè8ÎÅ˘Î≤ÎÏ÷Ï¯Î˝ÎÎÎβÎÎÏÎÎ΄ÏÎΔÎèBÎÅ˘Ï˘ÎÏÏ¿ÏÎ÷Î¯Î˛ÎÎÏÏν    ÏÎÏÎÏÎÏΉÎÏΔÏèOÎÅ˘Î˘ÏÎ˝Ï˝Î˜Ï„ÎÚÎÏ÷Ï˘˛ÎÎÎÏ˛ÎÏ˝ÎÎÎÎ΄ÏÎΔÎèkÏÅ˘Î˘ÎÎÏÎβÎÎÎÏÎβÎÎÏ˛Î˛ÎÎÎÎÎÎÎÎÎÏ˝ÎÎÏ˛ÎÏÎÏÎÎÏ˝ÎÎ÷ÎÒÎÎÎ◊ÎÎΔÎègÎÅ˘Ï˘ÎÏÏÎÏÎÏÎÏÎÏÏβ(ÎÏÎÏÎÏÎÎÏÎÏÎÏÏÏÎÏÎÏÏÎÏÎÏÏÏÎ˚ÏÎ÷ÎÎÏ’ÎÏΔÏè^ÏÅ˘Î˘ÎÎÎνÎÏ˚ÎÏÎÎÏÎÏÎÎÏÎÎÎÏ˝ÎνβÎÏ˝ÎÎ÷άÎÎΔÎèbÎÅ˘Î˘ÏÎβνÎÎÏÎÎÏβ ÎÎÏÎÏÎÎÏ˛Ï˛ÎÎβÎÏÎÏ˛ÎÎÎÏθÎÏ÷ϬÏÎΔÎè^ÎÅ˘ÏfiÏ÷ÏÎ÷AÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏΔÏè\ÎÅ˘ÎfiÎ÷ÎÏ’˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏÎΔÎèÏÅ˘Î≤ÎÎÅŸÎèÎÅ˘Ï≤ÏÎÅŸÏèbÏÅ˘˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏÎÎÅŸÎèÎÅ˘Î≤ÎÏÅŸÎèÎÅ˘Ï≤ÏÎÅŸÏèÎÅ˘Î≤ÎÏÅŸÎèÏÅ˘Î≤ÎÎÅŸÎèÎÅ˘Ï˘ÎÏÎÏæÏÎÅŸÏè#ÏÅ˘Î˙ν΀ÎÊÎÎÅŸÎèFÎÅ˘Î˙ν    ÏÎÏÎÎÏβÎÎÏνÎÎÎÎÎÏÎÎÏÎÎÏÁÎÏÅŸÎèò@@¯@¯(jhb?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú?“ˇ¸Ú“ˇ¸Ú¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ò@@į@įhj®b¡¡¡ ¸Ρ¿ Ã ˝#Ä$`à ˝bD@à ˝ÇÑ@à ˝zÇÑ@à ˝$Brà@à ˝DDêÄà ˝én‡a¿Ã¡¡¡¡˝ÙÄp˛0@“˝Äê˛@◊˝D¿®oB$B7‰»ŒíDŸ˝â04ë≠ ∫çJ≈â%öŸ˝E $ë.¢éÇBR°Ÿ˝     ·I"8DòÑÇí    !0Ÿ˝ ¿MrSHìñ    ƒ∫Mr&Ÿ˝    à&H•å0ådї⢟¸`¸—¸ ¸—¸¿¸—¡    ¸Ë     ˝… ˝õ“Ñ«À ˝$kI)À ˝z$JFÀ ˝"HåäÀ ˝D\îŒRÀ ˝Ñ)dâúÀ˚»˚»˚Ä…¡¸‡ <˛:ʿɛ˝˛DDÄÜ›˝ââ!%© Ñ(@¨thÅåiân1‘›˝íJ!*Q!0ñ¢AtòìATíS§ Z›˝ !KA0ßÅ$DìÅTî    $â›˝)BçAPlÇ()&e$I§›˝KúïD%…ÅàIìM-l¬Itöm¶›˝ç¯"â·› FI»≥\£HÁ$› ˝˙œ ˝‡˙œ¡¡˝Ü˛ `OÄ@‘˝I$Ä êë @‘¸—$uŒI¢1Åq√D'@÷˝í"RM¬Ç¢Dö—†÷¸éhàäN$Ѱú· ÷¸Üà#îò/ƒ¿â1Ç ÷˝    à%§≥A    dãg2@÷˝0pY8ÃAÅGò≈Ä÷˙@˝@˛’˙@˝Ä˛’˙‡˙8˛’¡¡ò@Äú¯Äú¯®jƒb¡¡¡¡¡¡¡¡¡¡¡¸Ä¿†¸8—¸
  12665. Ä@@—˝ ùtÑF[tó å“˝ FööÌi@.í“˝ Díúi¢pÄ$†“˝ »£0¢J#$¿ÄE “˝ I%f"ì%vôI§“˝
  12666. ˆYòíY§aÈÄ”¸@˝@–¸@˝@ – ¸8‡˝‡Õ¡˝
  12667. †¿˘Ä–˝
  12668. @    ÄHÄ”˝MX—
  12669. îÄQ$~ìx…‘˝È&¥$•ëDî§ì*‘¸
  12670. íI'8$Bë(DDí$‘òů@¯HHö˙‹Í?IJˇˇˇˇˇˇˇˇˇˇÃÃˇˇˇˇôôˇˇˇˇffˇˇˇˇ33ˇˇˇˇˇˇÃÃˇˇˇˇÃÃÃÃˇˇÃÃôô    ˇˇÃÃff
  12671. ˇˇÃÃ33 ˇˇÃà ˇˇôôˇˇ
  12672. ˇˇôôÃÃˇˇôôôôˇˇôôffˇˇôô33ˇˇôôˇˇffˇˇˇˇffÃÃˇˇffôôˇˇffffˇˇff33ˇˇffˇˇ33ˇˇˇˇ33ÃÃˇˇ33ôôˇˇ33ffˇˇ3333ˇˇ33ˇˇˇˇˇˇÃàˇˇôô!ˇˇff"ˇˇ33#ˇˇ$ÃÃˇˇˇˇ%ÃÃˇˇÃÃ&ÃÃˇˇôô'ÃÃˇˇff(ÃÃˇˇ33)ÃÃˇˇ*ÃÃÃÃˇˇ+ÃÃÃÃÃÃ,ÃÃÃÃôô-ÃÃÃÃff.ÃÃÃÃ33/ÃÃÃÃ0ÃÃôôˇˇ1ÃÃôôÃÃ2ÃÃôôôô3ÃÃôôff4ÃÃôô335ÃÃôô6ÃÃffˇˇ7ÃÃffÃÃ8ÃÃffôô9ÃÃffff:ÃÃff33;ÃÃff<ÃÃ33ˇˇ=ÃÃ33ÃÃ>ÃÃ33ôô?ÃÃ33ff@ÃÃ3333AÃÃ33BÃÃˇˇCÃÃÃÃDÃÃôôEÃÃffFÃÃ33GÃÃHôôˇˇˇˇIôôˇˇÃÃJôôˇˇôôKôôˇˇffLôôˇˇ33MôôˇˇNôôÃÃˇˇOôôÃÃÃÃPôôÃÃôôQôôÃÃffRôôÃÃ33SôôÃÃTôôôôˇˇUôôôôÃÃVôôôôôôWôôôôffXôôôô33YôôôôZôôffˇˇ[ôôffÃÃ\ôôffôô]ôôffff^ôôff33_ôôff`ôô33ˇˇaôô33ÃÃbôô33ôôcôô33ffdôô3333eôô33fôôˇˇgôôÃÃhôôôôiôôffjôô33kôôlffˇˇˇˇmffˇˇÃÃnffˇˇôôoffˇˇffpffˇˇ33qffˇˇrffÃÃˇˇsffÃÃÃÃtffÃÃôôuffÃÃffvffÃÃ33wffÃÃxffôôˇˇyffôôÃÃzffôôôô{ffôôff|ffôô33}ffôô~ffffˇˇffffÃÃÄffffôôÅffffffÇffff33ÉffffÑff33ˇˇÖff33ÃÃÜff33ôôáff33ffàff3333âff33äffˇˇãffÃÃåffôôçfffféff33èffê33ˇˇˇˇë33ˇˇÃÃí33ˇˇôôì33ˇˇffî33ˇˇ33ï33ˇˇñ33ÃÃˇˇó33ÃÃÃÃò33ÃÃôôô33ÃÃffö33ÃÃ33õ33ÃÃú33ôôˇˇù33ôôÃÃû33ôôôôü33ôôff†33ôô33°33ôô¢33ffˇˇ£33ffÃç33ffôô•33ffff¶33ff33ß33ff®3333ˇˇ©3333ÃÙ3333ôô´3333ff¨333333≠3333Æ33ˇˇØ33ÃÃ∞33ôô±33ff≤3333≥33¥ˇˇˇˇµˇˇÃÃ∂ˇˇôô∑ˇˇff∏ˇˇ33πˇˇ∫ÃÃˇˇªÃÃÃúÃÃôôΩÃÃffæÃÃ33øÃÿôôˇˇ¡ôôÃìôôôô√ôôffƒôô33≈ôôΔffˇˇ«ffÃûffôô…ffff ff33ÀffÃ33ˇˇÕ33ÃÃŒ33ôôœ33ff–3333—33“ˇˇ”ÃÑôô’ff÷33◊ÿˇˇˇŸ˘`˘`˘`⁄Ú–Ú–Ú–€Ï@Ï@Ï@‹Â∞Â∞Â∞›fl fl fl fiÿêÿêÿêfl“““‡ÀpÀpÀp·ƒ‡ƒ‡ƒ‡‚æPæPæP„∑¿∑¿∑¿‰±0±0±0™†™†™†Ê§§§ÁùÄùÄùÄËñññÈê`ê`ê`Íâ–â–â–ÎÉ@É@É@Ï|∞|∞|∞Ìv v v ÓoêoêoêÔiiibpbpbpÒ[‡[‡[‡ÚUPUPUPÛN¿N¿N¿ÙH0H0H0ıA†A†A†ˆ;;;˜4Ä4Ä4į---˘'`'`'`˙ – – –˚@@@¸∞∞∞˝
  12673.  
  12674.  
  12675.  ˛êêê@¯(jhb'EÎÅ˘Ï˙Ï˝ÎÏÏÎÎÏÎÎÏÎÏνÏÎÏÎÏÎÎÏÏÊÏÎÅŸÏèEÎÅ˘Î˙ν ÏÎÎÎÎÎÏ˛Ï˝Î˛ÎÏÎÏÎÎÎÊÎÏÅŸÎèEÏÅ˘Î˘ÎÎÏÎÏÎÎÏÎÏÎθÏÎÎÏÎÏÎÎÏÎÎÁÎÎÅŸÎèÎÅ˘Ï≤ÏÎÅŸÏèÏÅ˘Î≤ÎÎÅŸÎèÎÅ˘Î≤ÎÏÅŸÎèÎÅ˘Ï≤ÏÎÅŸÏèÎÅ˘Î≤ÎÏÅŸÎèbÏÅ˘˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏÎÎÅŸÎèÎÅ˘Ï≤ÏÎÅŸÏèÏÅ˘Î≤ÎÎÅŸÎèÎÅ˘Î≤ÎÏÅŸÎèÎÅ˘Ï≤ÏÎÅŸÏèÎÅ˘ÎËÎÃÎÏÅŸÎè+ÏÅ˘Î˘ÎÎÏÎΘÎÎθΑÎÎÅŸÎè(ÎÅ˘Ï˙ÏÎÎˆÎ˘Ï‘ÏÎÅŸÏè2ÏÅ˘Î¯Î¸ÎÎÏ˛ÎÎÎβÎÏ’ÎÎÅŸÎè1ÎÅ˘Î¯Î˝ÎÏÎÏÎÎÎÏÎÏ”ÎÏÅŸÎè3ÎÅ˘Ï¯Ï˛ÏÏÎÎÏ˛
  12676. ÏÎÎÎÏÎÎÏ‘ÏÎÅŸÏè2ÎÅ˘Î˘ÏÎβÎÏ˛Î˛    ÎÎÏÎÏ”ÎÏÅŸÎèÏÅ˘ÎÒÎÎΫÎÎÅŸÎèÎÅ˘ÏÏÎ≈ÏÎÅŸÏèÏÅ˘Î≤ÎÎÅŸÎèÎÅ˘Î≤ÎÏÅŸÎècÎÅ˘QÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÏÎÅŸÏèÎÅÅÅÎèÏÅÅÅÎèÎÅÅÅÏèÏÅÅÅÎèÎÅÅÅÎèÎÅÅÅÏèÎÅÅÅÎèÏÅÅÅÎèÎÅÅÅÏèÏÅÅÅÎèÎÅÅÅÎèÎÅÅÅÏèâÎÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏÎèܲ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎÏ˛ÎèÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâÅÅÅâòů@įHHö˘àÍ@IJˇˇˇˇˇˇˇˇˇˇÃÃˇˇˇˇôôˇˇˇˇffˇˇˇˇ33ˇˇˇˇˇˇÃÃˇˇˇˇÃÃÃÃˇˇÃÃôô    ˇˇÃÃff
  12677. ˇˇÃÃ33 ˇˇÃà ˇˇôôˇˇ
  12678. ˇˇôôÃÃˇˇôôôôˇˇôôffˇˇôô33ˇˇôôˇˇffˇˇˇˇffÃÃˇˇffôôˇˇffffˇˇff33ˇˇffˇˇ33ˇˇˇˇ33ÃÃˇˇ33ôôˇˇ33ffˇˇ3333ˇˇ33ˇˇˇˇˇˇÃàˇˇôô!ˇˇff"ˇˇ33#ˇˇ$ÃÃˇˇˇˇ%ÃÃˇˇÃÃ&ÃÃˇˇôô'ÃÃˇˇff(ÃÃˇˇ33)ÃÃˇˇ*ÃÃÃÃˇˇ+ÃÃÃÃÃÃ,ÃÃÃÃôô-ÃÃÃÃff.ÃÃÃÃ33/ÃÃÃÃ0ÃÃôôˇˇ1ÃÃôôÃÃ2ÃÃôôôô3ÃÃôôff4ÃÃôô335ÃÃôô6ÃÃffˇˇ7ÃÃffÃÃ8ÃÃffôô9ÃÃffff:ÃÃff33;ÃÃff<ÃÃ33ˇˇ=ÃÃ33ÃÃ>ÃÃ33ôô?ÃÃ33ff@ÃÃ3333AÃÃ33BÃÃˇˇCÃÃÃÃDÃÃôôEÃÃffFÃÃ33GÃÃHôôˇˇˇˇIôôˇˇÃÃJôôˇˇôôKôôˇˇffLôôˇˇ33MôôˇˇNôôÃÃˇˇOôôÃÃÃÃPôôÃÃôôQôôÃÃffRôôÃÃ33SôôÃÃTôôôôˇˇUôôôôÃÃVôôôôôôWôôôôffXôôôô33YôôôôZôôffˇˇ[ôôffÃÃ\ôôffôô]ôôffff^ôôff33_ôôff`ôô33ˇˇaôô33ÃÃbôô33ôôcôô33ffdôô3333eôô33fôôˇˇgôôÃÃhôôôôiôôffjôô33kôôlffˇˇˇˇmffˇˇÃÃnffˇˇôôoffˇˇffpffˇˇ33qffˇˇrffÃÃˇˇsffÃÃÃÃtffÃÃôôuffÃÃffvffÃÃ33wffÃÃxffôôˇˇyffôôÃÃzffôôôô{ffôôff|ffôô33}ffôô~ffffˇˇffffÃÃÄffffôôÅffffffÇffff33ÉffffÑff33ˇˇÖff33ÃÃÜff33ôôáff33ffàff3333âff33äffˇˇãffÃÃåffôôçfffféff33èffê33ˇˇˇˇë33ˇˇÃÃí33ˇˇôôì33ˇˇffî33ˇˇ33ï33ˇˇñ33ÃÃˇˇó33ÃÃÃÃò33ÃÃôôô33ÃÃffö33ÃÃ33õ33ÃÃú33ôôˇˇù33ôôÃÃû33ôôôôü33ôôff†33ôô33°33ôô¢33ffˇˇ£33ffÃç33ffôô•33ffff¶33ff33ß33ff®3333ˇˇ©3333ÃÙ3333ôô´3333ff¨333333≠3333Æ33ˇˇØ33ÃÃ∞33ôô±33ff≤3333≥33¥ˇˇˇˇµˇˇÃÃ∂ˇˇôô∑ˇˇff∏ˇˇ33πˇˇ∫ÃÃˇˇªÃÃÃúÃÃôôΩÃÃffæÃÃ33øÃÿôôˇˇ¡ôôÃìôôôô√ôôffƒôô33≈ôôΔffˇˇ«ffÃûffôô…ffff ff33ÀffÃ33ˇˇÕ33ÃÃŒ33ôôœ33ff–3333—33“ˇˇ”ÃÑôô’ff÷33◊ÿˇˇˇŸ˘`˘`˘`⁄Ú–Ú–Ú–€Ï@Ï@Ï@‹Â∞Â∞Â∞›fl fl fl fiÿêÿêÿêfl“““‡ÀpÀpÀp·ƒ‡ƒ‡ƒ‡‚æPæPæP„∑¿∑¿∑¿‰±0±0±0™†™†™†Ê§§§ÁùÄùÄùÄËñññÈê`ê`ê`Íâ–â–â–ÎÉ@É@É@Ï|∞|∞|∞Ìv v v ÓoêoêoêÔiiibpbpbpÒ[‡[‡[‡ÚUPUPUPÛN¿N¿N¿ÙH0H0H0ıA†A†A†ˆ;;;˜4Ä4Ä4į---˘'`'`'`˙ – – –˚@@@¸∞∞∞˝
  12679.  
  12680.  
  12681.  ˛êêê@įhj®b'ÅÅÅâÅÅÅâÅÅÅâ#Ÿ˛ˇˇ˝ˇ¸ˇ˙˛ˇ¯ˇˇ¸ˇÅÅÅ‹,⁄ˇ˛ˇ˛ˇˇ˛ˇˇ˘ˇ¯ˇˇ˛ˇˇÅÅÅ‹+€ˇ˝ˇˇˇˇ˛ˇ˘ˇ¯ˇ˛ˇ˛ˇÅÅÅ€$‹ˇ˘˛ˇ¸ˇ˘ˇ˘ˇ˝ˇ˛ˇÅÅÅ€)‹ˇ˛˝ˇˇˇ¸ˇ˘ˇ˘ˇ˝ˇ˛ˇÅÅÅ€2‹ˇ˝ˇˇ˛ˇ˝ˇ˛ˇˇ¸˛ˇˇ˛ˇ˝ˇÅÅÅ€/‹ˇ˛ˇ˛ˇ˛ˇ˛ˇ˘ˇ˝ˇ˝ˇˇ˝ˇÅÅÅ⁄%€˛ˇ˛˛ˇˇˇ˛ˇ˚˚ˇ˚ˇˇ˝˛ˇÅÅÅ€ÅÅÅâÅÅÅâÅÅÅâÅÅÅâ&€˚ˇˇÒˇ¯ˇÙˇˇ˛ˇ„ˇˇ¸ˇÅÅã2⁄ˇ˛ˇˇˇ˘ˇˇıˇˇˇ‚ˇÔˇ˜ˇÓˇÅÅ∑z€ˇˇ˛ˇˇˇˆˇ¯ˇÙˇˇˇˇ˝ˇˇ˝ˇˇ˝ˇ˙ˇˇˇˇ˛ˇ˝ˇ˛ˇˇ˛ˇ˚¸ˇ    ˇˇˇˇ˛ˇˇ˛ˇ
  12682. ˇˇˇˇ˛ˇÅūր˛ˇ˛ˇˇˇˇ¯ˇ¯ˇÛˇ˛    ˇˇˇˇˇ˛ˇˇˇˇˇˇ˝ˇˇˇ˛ˇˇˇ˛
  12683. ˇˇˇˇˇˇ˚ˇˇˇ˛ˇˇˇ˛ ˇˇˇˇˇ˛ ˇˇˇˇˇˇÅÅ»w€ˇˇ˛ˇˇˇ˜ˇ¯ˇÚ ˇˇˇˇˇ˛ˇˇ˛ˇ¸ˇ˛ˇˇ˛ˇˇ˛˛ˇˇ¸ˇ˙ˇˇ˝ˇˇˇˇ˚ˇˇˇ˝ˇ˛˛ˇÅÅ«{‹ˇ˚ˇˇˇ˜ˇ˛ˇ˝ˇˆˇ˛ ˇˇˇˇˇ˛ˇ˛˛ˇ˚ˇ˛ˇˇ˛ˇˇˇˇ˛ˇ˝ˇ¯ˇˇ¸ˇˇˇˇ¸ˇˇˇ˝ˇˇˇÅÅ≈ዡ˚ˇˇˇˇ˜ˇ¯ˇı
  12684. ˇˇˇˇˇˇˇ˛ˇ ˇˇˇˇˇ˛ˇ˛ˇˇˇ˛ˇˇ˛ˇˇˇˇ¸ˇ˛ˇ˛ˇˇ˛ˇ ˇˇˇˇˇ˛ˇˇ˛ˇˇˇÅŻě˛ˇ¸ˇˇˇ˛ˇ˚˛ˇ˙˛ˇ˜
  12685. ˇˇˇˇˇ˛ˇˇˇˇˇ˛ˇˇ˚˛ˇ˛ˇˇ˝ˇ˛ˇˇ˛ˇˇˇ˚˛ˇˇ˝ˇˇˇˇ˛ˇˇ˛ˇˇˇˇ˛ˇ˝ˇˇÅÅΔ”ˇˇˇœˇËˇÅÅ┡˛ˇœˇÍˇˇÅÅ⓲ˇœ˛ˇÍˇÅÅàÅÅÅâŸ˛ˇˇˇˇ¸ˇÅÅÅœ⁄ˇ˛ˇÓˇÅÅÅ…0€ˇ˝
  12686. ˇˇˇˇˇ˝ˇˇˇˇ˝ˇˇˇ˛˛ˇÅÅÅŸ2‹ˇ˙ˇˇˇˇ˛ˇˇˇˇˇˇˇˇˇˇˇÅÅÅŸ/‹ˇ˛˝ˇˇ˛ˇˇ˛ˇˇˇˇ˛ˇˇ˚ˇÅÅÅ◊0‹ˇ˝ˇ˛ˇˇˇ˛ˇ˛ˇˇˇ˛ˇˇ˙ˇÅÅÅÿ5‹ˇ˛ˇ˛ˇ˛ˇ˛ˇ
  12687. ˇˇˇˇˇ˛ˇˇˇˇÅÅÅÿ.€˛ˇ˝ˇ˝ˇˇˇˇˇˇˇ˛ˇˇˇ˛ˇÅÅÅ◊  ˇÅÅÅ¡  ˇÅÅÅ¡ À˛ˇÅÅŬÅÅÅâNŸ˛ˇ¯ˇ˙ˇˇ˝˝ˇÂ˛ˇˇ˛ˇˇˇ˙ˇ˝ˇˇÔ˛ˇˆˇ˚ˇ˜ˇˇ¸ˇˇıˇÎˇˇÅÅÊJ⁄ˇ˛ˇˇ¸ˇˇÁˇ˛ˇ˛ˇ˛ˇ¯ˇ˛ˇÌˇÓˇˆˇ˝ˇˇÎˇÛˇÅÅʨ€ˇ˝ˇˇˇ˛ˇˇˇ˛ˇˇˇ˝ˇˇˇˇˇˇˇˇˇ¸ˇ˝ˇ˝ˇˇ¯ˇˇ˛ˇ˛ˇ˛ˇˇˇ˚ˇˇˇˇ˛˛ˇˇ˛ˇˇˇ˛ˇ˚ˇˇ˛ˇˇ˛ˇˇˇˇˇ˛ˇˇˇˇ˛ˇ˛ˇˇ˛˛ˇˇˇÅÅÁ≠‹ˇ¸ˇˇ˛ˇˇˇˇˇˇ˛ˇ˝ ˇˇˇˇˇˇ˛ˇˇ˝ˇ˜ˇˇ˜ ˇˇˇˇˇˇˇ˛ˇˇ¸ˇ˛ˇˇˇˇˇ˛    ˇˇˇˇˇ¸ˇˇˇˇˇˇˇˇˇ˛ˇˇˇˇˇˇˇˇˇˇˇÅÅË•‹ˇ¸ˇˇˇ˝ˇˇ˚ˇˇ˝ˇ˝ˇ˛ˇˇˇˇˇˇˇ¸ˇ˛˝ˇ˛ˇˇ¯ˇˇˇ˛ˇ˛ˇˇˇˇ˚ˇˇˇ˛ˇ˛ˇˇˇ˛ˇ˚ˇˇˇˇˇˇˇ˚ ˇˇˇˇˇ˛ˇˇ˛ˇˇÅÅ˶‹ˇ˝ˇˇˇ˛ˇˇ¸ˇˇ˛ˇ˝ˇ˝ˇˇˇ˛ˇˇˇˇ¸ˇ˝ˇ˝ˇˇ¯ˇ˛ˇˇˇˇ¸ˇˇˇˇ¸ˇ˛ˇˇ¸ ˇˇˇˇˇˇ˙ˇˇˇˇˇˇˇ¸ˇ˛ˇˇˇˇ˛ˇ˝ˇˇˇÅÅÁµ‹ˇ˛ˇˇ˛ˇ˛ˇ ˇˇˇˇˇ˛ˇ˝ˇˇ˛ˇˇˇˇ˚ˇ˛ˇ˝ˇ˛ˇ˘ˇ˛ˇˇˇˇˇˇˇ˚ˇˇˇˇˇˇˇˇˇˇˇˇˇˇˇ˝
  12688. ˇˇˇˇ˛ˇˇˇˇˇˇˇˇˇˇˇ˛ ˇˇˇˇˇˇÅÅË߀˛ˇ˛ˇˇˇ˛ˇˇˇ˛ˇˇ¸ˇ¸ˇ˛ˇˇ˛ˇˇ˘˛ˇ˝˛ˇ˛ˇˇ˝ˇˇ˛ˇ˛ˇˇ˝ˇˇ˚˛ˇˇˇ˛ˇˇ˛ˇˇˇˇˇ¸˛ˇˇ˛ˇˇˇ˛ˇˇ˛    ˇˇˇˇ˛˛ˇ˛ˇˇˇÅÅÁ€ˇ˝ˇæˇÅÅÅ˘‹˚ˇæˇÅÅůÅÅÅâÅÅÅâ.⁄ˇˇ˝ˇˇ˝ˇˇ‚ˇ¸ˇÛˇˇ˚ˇ¸ˇÈˇÅÅõ;€ˇˇˇˇˇˇ˜ˇËˇÙˇˇ˝ˇˇ˛ˇ˜ˇÛˇÅÅõoŸˇˇˇ˛ˇˇˇ˛˛ˇˇ˛ˇ˛ˇ˝ˇˇˇˇˇˇˇ˛ˇˆˇˇ˛ˇˇ˚ˇ˛˛ˇˇ˛ˇ˛˛ˇ˝ˇˇˇ˛ˇ˝ˇ˛ˇˇÅÅ´x€ˇˇ˛ˇ˛ˇ˛ˇˇ˚ ˇˇˇˇˇˇ˛ˇ˛ˇˇˇˇˇˇˇˇ˘ˇˇ˝ˇˇ¸ˇ˚ˇˇˇˇ˛ˇˇ˛ˇˇˇˇˇˇˇˇ˛ˇˇˇÅŨjŸˇ˛˛ˇˇˇˇ˚ˇˇˇ˛ˇ˚ˇˇˇˇ˛ˇˇˇ˛ˇˆˇˇˇ˝ˇ˙ˇˇˇ˝ˇ¸ˇˇ˛ˇ˛ˇ˝ˇˇÅŨgŸˇ˝ˇˇˇ˛ˇ¸ˇ˛ˇˇ¸ˇ¸ˇˇˇˇˇˇˇˇˇÙˇ˚ˇ˛ˇ˚